探索Dart中Map<dynamic, dynamic>类型不能直接赋值给Map<String, dynamic>的原因
为什么会想到这个问题
在传递数据的时候,map类型与要求不符合
type '_InternalLinkedHashMap<dynamic, dynamic>' is not a subtype of type 'Map<String, dynamic>'
首先说解决方式
- 方法一
String jsonString = '{"name": "John", "age": 30}';
Map<dynamic, dynamic> user = jsonDecode(jsonString);
Map<String, dynamic> userMap = Map<String, dynamic>.from(user);
- 方法二
String jsonString = '{"name": "John", "age": 30}';
Map<dynamic, dynamic> user = jsonDecode(jsonString);
Map<String, dynamic> userMap = user.cast();
为什么不能直接赋值
在泛型类型中,Map<dynamic, dynamic>
和 Map<String, dynamic>
被认为是不同的类型,即使它们可能包含相同的内容。类型系统不能保证 Map<dynamic, dynamic>
的键是 String
类型,因此不能直接赋值。
Map<String, dynamic>
可以给 Map<dynamic, dynamic>
直接赋值吗?
String jsonString = '{"name": "John", "age": 30}';
Map<String, dynamic> user = jsonDecode(jsonString);
Map<dynmic, dynamic> userMap = user;
上边的代码是没有问题的,也就是说是可以直接赋值的。
可以赋值的原因是什么?
在 Dart 中,泛型类型是协变的。这意味着你可以将一个 Map<String, dynamic>
赋值给一个 Map<dynamic, dynamic>
。这是因为 Map<dynamic, dynamic>
可以接受任何类型的键和值,而 Map<String, dynamic>
的键和值类型是 String
和 dynamic
,这满足了 Map<dynamic, dynamic>
的要求。
协变(Covariance) :允许将一个更具体的类型赋值给一个更通用的类型。例如,你可以将
List<String>
赋值给List<Object>
。逆变(Contravariance) :允许将一个更通用的类型赋值给一个更具体的类型。Dart 默认不支持这种逆变行为。
Dart不支持逆变,那dynamic类型的字符串可以赋值给String类型吗?
dynamic someValue = "Hello, World!";
String stringValue = someValue; // 这是允许的
print(stringValue); // 输出: Hello, World!
这也是没有问题的,也是可以直接赋值的。
这个的原因是什么呢?
Dart 中的 dynamic
类型具有特殊的属性,使它可以与任何类型进行互操作。具体来说,dynamic
类型表示任何类型的对象,因此编译器允许将 dynamic
类型的值分配给具体类型的变量。这种操作在编译时不会报错,但可能在运行时导致错误。
dynamic
类型的宽容性:dynamic
类型在 Dart 中是一个特殊类型,可以代表任何类型的值。它允许开发者在编译时不确定具体类型的情况下进行编程操作。类型安全:虽然 Dart 是强类型语言,但
dynamic
提供了一种方式,可以暂时放弃类型检查。这意味着编译器不会对dynamic
类型的值进行严格的类型检查。
转载自:https://juejin.cn/post/7381472292428677157