You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Dart中实现返回「常量引用」的getter以暴露不可修改的列表

Dart 实现对外只读、内部可修改列表的方案

Dart 标准库已经提供了成熟的封装方案,不需要你自行封装length、map等列表方法,有两种常用实现可选:

方案1:返回不可修改列表视图(推荐,实时同步)

使用dart:collection包中的UnmodifiableListView,它是原列表的只读代理,不会额外复制列表内容,内部列表更新时外部拿到的视图也会同步更新,外部尝试修改列表会直接抛出异常。
示例代码:

import 'dart:collection';

class ListContainer {
  // 内部维护的私有可修改列表
  final List<String> _innerList = [];

  // 对外暴露的只读视图
  UnmodifiableListView<String> get publicList => UnmodifiableListView(_innerList);

  // 内部方法可以正常修改原列表
  void addItem(String item) {
    _innerList.add(item);
  }

  void removeLastItem() {
    if (_innerList.isNotEmpty) _innerList.removeLast();
  }
}

调用验证:

void main() {
  final container = ListContainer();
  container.addItem('test');
  print(container.publicList.first); // 正常读取,输出test
  print(container.publicList.length); // 正常读取长度,输出1
  container.publicList.add('new item'); // 抛出 UnsupportedError,禁止修改
}

方案2:返回不可修改列表快照

如果你不需要外部拿到的列表和内部列表实时同步,只需要获取当前时刻的列表副本,可以直接返回List.unmodifiable封装的不可修改副本:
示例代码:

class ListContainer {
  final List<String> _innerList = [];

  // 对外返回当前列表的不可修改副本,后续内部列表修改不会影响已返回的副本
  List<String> get publicList => List.unmodifiable(_innerList);

  void addItem(String item) => _innerList.add(item);
}

两种方案的选择建议

  • 优先选UnmodifiableListView:零拷贝、内存开销低,和内部列表数据实时同步,适合绝大多数场景
  • 选List.unmodifiable的场景:需要获取某一时刻的列表快照,不希望后续内部列表的修改影响外部已经拿到的列表

注意:上述两种方案仅禁止修改列表本身(增、删、替换元素),如果列表中的元素是可修改的对象,外部依然可以修改元素的内部属性。如果需要完全不可变,需要同时将列表元素实现为不可变类型。

内容的提问来源于stack exchange,提问作者splaytreez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 13:15:03