Dart MapView
最后修改于 2025 年 4 月 4 日
在 Dart 中,MapView 是 Map 的一个不可修改的视图。它提供对底层 map 数据的只读访问,同时阻止修改。
MapView 实现 Map 接口,但对于会修改 map 的操作会抛出 UnsupportedError。它对于安全地暴露 map 数据很有用。
创建 MapView
创建 MapView 最简单的方法是使用 MapView.of 构造函数。
main.dart
import 'dart:collection'; void main() { var originalMap = {'a': 1, 'b': 2, 'c': 3}; var view = MapView.of(originalMap); print(view); print(view['b']); // Access works try { view['d'] = 4; // Will throw } catch (e) { print(e); // UnsupportedError } }
我们从一个现有的 map 创建一个 MapView。虽然我们可以读取值,但任何尝试修改视图的操作都会抛出 UnsupportedError。
$ dart main.dart {a: 1, b: 2, c: 3} 2 UnsupportedError: Cannot modify unmodifiable map
带不同 Map 类型的 MapView
MapView 可以与任何 Map 实现一起工作,包括 HashMap 和 LinkedHashMap。
main.dart
import 'dart:collection'; void main() { var hashMap = HashMap<String, int>(); hashMap.addAll({'x': 10, 'y': 20, 'z': 30}); var linkedMap = LinkedHashMap<String, int>(); linkedMap.addAll({'first': 1, 'second': 2}); var hashView = MapView.of(hashMap); var linkedView = MapView.of(linkedMap); print('HashMap view: $hashView'); print('LinkedHashMap view: $linkedView'); }
这表明 MapView 在不同的 Map 实现中一致工作。该视图保留了原始 map 的特性。
$ dart main.dart HashMap view: {x: 10, z: 30, y: 20} LinkedHashMap view: {first: 1, second: 2}
MapView 操作
MapView 支持 Map 接口的所有读取操作。
main.dart
import 'dart:collection'; void main() { var scores = {'Alice': 90, 'Bob': 85, 'Charlie': 95}; var scoreView = MapView.of(scores); print('Keys: ${scoreView.keys}'); print('Values: ${scoreView.values}'); print('Length: ${scoreView.length}'); print('Contains Alice: ${scoreView.containsKey('Alice')}'); print('Alice\'s score: ${scoreView['Alice']}'); scoreView.forEach((k, v) => print('$k: $v')); }
所有不修改的 Map 操作在 MapView 上都能正常工作。该视图反映了对原始 map 所做的更改。
$ dart main.dart Keys: (Alice, Bob, Charlie) Values: (90, 85, 95) Length: 3 Contains Alice: true Alice's score: 90 Alice: 90 Bob: 85 Charlie: 95
原始 Map 的实时视图
MapView 提供了一个实时视图,可以反映对原始 map 的更改。
main.dart
import 'dart:collection'; void main() { var original = {'a': 1, 'b': 2}; var view = MapView.of(original); print('Initial view: $view'); original['c'] = 3; print('After original modification: $view'); original.remove('a'); print('After original removal: $view'); }
对原始 map 的更改会立即在 MapView 中可见。这使得 MapView 非常适合需要安全共享数据的场景。
$ dart main.dart Initial view: {a: 1, b: 2} After original modification: {a: 1, b: 2, c: 3} After original removal: {b: 2, c: 3}
将 MapView 与其他集合结合使用
MapView 可以与其他不可修改的集合结合使用,以实现完全安全。
main.dart
import 'dart:collection'; void main() { var data = { 'users': ['Alice', 'Bob'], 'scores': [90, 85], 'active': true }; var unmodifiableMap = UnmodifiableMapView(data); var unmodifiableLists = unmodifiableMap.map( (key, value) => MapEntry( key, value is List ? List.unmodifiable(value) : value ) ); print(unmodifiableLists); try { unmodifiableLists['users'].add('Charlie'); // Fails } catch (e) { print(e); // UnsupportedError } }
我们通过将 MapView 与不可修改的列表结合来创建一个完全不可修改的结构。这可以在所有级别上阻止修改。
$ dart main.dart {users: [Alice, Bob], scores: [90, 85], active: true} UnsupportedError: Cannot add to an unmodifiable list
最佳实践
- 数据安全: 当你需要共享 map 数据而不允许修改时,请使用 MapView。
- 性能: MapView 的开销很小,因为它不复制数据。
- 不可变性: 与其他不可修改的集合结合使用,以实现完全不可变。
- 文档: 清晰记录 API 何时返回 MapView,以设定适当的期望。
来源
本教程通过实际示例介绍了 Dart 的 MapView,演示了其创建不可修改 map 视图的关键功能和用法模式。
作者
列出 所有 Dart 教程。