Dart UnmodifiableMapView
最后修改于 2025 年 4 月 4 日
在 Dart 中,UnmodifiableMapView 是 Map 的一个不可修改视图。它在阻止修改的同时,提供了对现有 Map 的只读访问。
UnmodifiableMapView
实现了 Map
接口,但对修改操作会抛出异常。它对于安全地暴露内部 Map 非常有用。
创建 UnmodifiableMapView
创建 UnmodifiableMapView 的最简单方法是使用构造函数。
main.dart
import 'dart:collection'; void main() { var originalMap = {'a': 1, 'b': 2, 'c': 3}; var unmodifiableView = UnmodifiableMapView(originalMap); print(unmodifiableView); try { unmodifiableView['d'] = 4; // Throws } catch (e) { print('Error: $e'); } }
我们创建了一个普通 Map 的不可修改视图。尝试修改它会抛出 UnsupportedError。视图会反映原始 Map 的更改。
$ dart main.dart {a: 1, b: 2, c: 3} Error: Unsupported operation: Cannot modify unmodifiable map
带 Map 方法的 UnmodifiableMapView
UnmodifiableMapView 支持 Map 接口的所有读取操作。
main.dart
import 'dart:collection'; void main() { var scores = {'Alice': 95, 'Bob': 87, 'Charlie': 92}; var view = UnmodifiableMapView(scores); print('Alice\'s score: ${view['Alice']}'); print('Contains Bob? ${view.containsKey('Bob')}'); print('Keys: ${view.keys}'); print('Values: ${view.values}'); print('Length: ${view.length}'); }
我们演示了 UnmodifiableMapView 的各种读取操作。所有这些操作与普通 Map 的工作方式相同,但可以防止修改。
$ dart main.dart Alice's score: 95 Contains Bob? true Keys: (Alice, Bob, Charlie) Values: (95, 87, 92) Length: 3
来自原始 Map 的动态更新
UnmodifiableMapView 会反映对原始底层 Map 所做的更改。
main.dart
import 'dart:collection'; void main() { var original = {'x': 10, 'y': 20}; var view = UnmodifiableMapView(original); print('Initial view: $view'); original['z'] = 30; print('After original modification: $view'); original.remove('x'); print('After original removal: $view'); }
对原始 Map 的更改会立即在视图中可见。视图本身保持不可修改,而原始 Map 仍然可以更改。
$ dart main.dart Initial view: {x: 10, y: 20} After original modification: {x: 10, y: 20, z: 30} After original removal: {y: 20, z: 30}
迭代 UnmodifiableMapView
UnmodifiableMapView 支持所有标准的 Map 迭代方法。
main.dart
import 'dart:collection'; void main() { var colors = {'red': '#FF0000', 'green': '#00FF00', 'blue': '#0000FF'}; var unmodifiableColors = UnmodifiableMapView(colors); print('Keys:'); for (var key in unmodifiableColors.keys) { print(key); } print('\nValues:'); for (var value in unmodifiableColors.values) { print(value); } print('\nEntries:'); unmodifiableColors.forEach((key, value) => print('$key: $value')); }
我们演示了三种迭代 UnmodifiableMapView 的方法。视图保持与原始 Map 相同的迭代顺序。
$ dart main.dart Keys: red green blue Values: #FF0000 #00FF00 #0000FF Entries: red: #FF0000 green: #00FF00 blue: #0000FF
带自定义对象的 UnmodifiableMapView
UnmodifiableMapView 与自定义对象一样,可以像普通 Map 一样工作。
main.dart
import 'dart:collection'; class Product { final String id; final String name; Product(this.id, this.name); @override bool operator ==(Object other) => identical(this, other) || other is Product && id == other.id && name == other.name; @override int get hashCode => id.hashCode ^ name.hashCode; } void main() { var products = { Product('p1', 'Laptop'): 999, Product('p2', 'Phone'): 699, }; var unmodifiableProducts = UnmodifiableMapView(products); var searchKey = Product('p1', 'Laptop'); print('Laptop price: \$${unmodifiableProducts[searchKey]}'); try { unmodifiableProducts[Product('p3', 'Tablet')] = 299; } catch (e) { print('Error: $e'); } }
我们将自定义 Product 对象用作 UnmodifiableMapView 中的键。视图在防止修改的同时正确处理键查找。
$ dart main.dart Laptop price: $999 Error: Unsupported operation: Cannot modify unmodifiable map
最佳实践
- 不可变暴露:用于安全地暴露内部 Map。
- 性能:与原始 Map 相比没有额外开销。
- 文档:清晰地将返回的视图记录为不可修改。
- 空安全:与不可空类型配合良好。
来源
本教程通过实际示例涵盖了 Dart 的 UnmodifiableMapView,演示了其关键特性和用法模式。
作者
列出 所有 Dart 教程。