Dart中map()方法类型转换疑问:第三种用法为何报错?
问题解释:Dart中第三种map()用法报错的原因
首先明确两个关键前提:
json.decode()返回的类型是dynamic,但实际运行时它是List<dynamic>。- Dart的泛型在运行时是严格校验的,
List<dynamic>和List<Foo>是完全独立的类型,不能直接互相赋值。
接下来拆解三个方法的差异:
1. getFoosCast() 正常运行
这里调用了data.map<Foo>(Foo.fromJson),显式指定了map的泛型参数为Foo。这会让Dart在编译阶段就确定,这个map操作返回的是Iterable<Foo>,后续调用toList()时,会基于这个泛型生成List<Foo>,和函数的返回类型List<Foo>完全匹配,所以运行无报错。
2. getFoosUntyped() 正常运行
这个函数没有指定返回类型,Dart会自动推断返回值类型。虽然map<Foo>同样返回Iterable<Foo>、toList()生成List<Foo>,但因为函数没写返回类型,最终推断结果是dynamic。打印时dynamic类型的值可以正常输出,所以不会报错——但如果把这个函数的返回值赋值给List<Foo>类型的变量,编译阶段就会提示类型问题。
3. getFoos() 抛出类型错误
这里调用的是data.map(Foo.fromJson),没有显式指定泛型参数。因为data的类型是dynamic,Dart编译时无法确定map应该使用什么泛型,只能默认按dynamic处理:
map操作返回的是Iterable<dynamic>(即使每个元素实际是Foo对象)- 调用
toList()后得到的是List<dynamic> - 但函数的返回类型要求是
List<Foo>,运行时Dart会严格检查类型,List<dynamic>无法被当作List<Foo>返回,所以抛出type 'List<dynamic>' is not a subtype of 'List<Foo>'的异常。
简单总结:当调用dynamic类型对象的map方法时,必须显式指定泛型参数,否则Dart会默认生成Iterable<dynamic>,后续的toList()也会是List<dynamic>,无法匹配List<Foo>的返回类型要求。
内容的提问来源于stack exchange,提问作者Matthieu Dazy
相关产品推荐
相关产品推荐

