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 教程。