如何在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
相关产品推荐
相关产品推荐

