关于使用Dart's map()进行类型转换的问题

busg9geu  于 2023-07-31  发布在  其他
关注(0)|答案(1)|浏览(140)

我想我一定是在Dart执行运行时类型检查的方式上遗漏了什么。谁能给我解释一下下面map()的第三个用法是怎么错的?

import 'dart:convert';

class Foo {
  final int bar;
  Foo.fromJson(data) : bar = data['bar'];
}

void main() {
  final data = json.decode('[{"bar": 42}]');
  
  List<Foo> getFoosCast() => data.map<Foo>(Foo.fromJson).toList();
  print(getFoosCast()); // [Instance of 'Foo']

  // return type is inferred as 'dynamic' despite the cast on map<>?
  getFoosUntyped() => data.map<Foo>(Foo.fromJson).toList();
  print(getFoosUntyped()); // [Instance of 'Foo']

  List<Foo> getFoos() => data.map(Foo.fromJson).toList();
  print(getFoos()); // Unhandled exception: type 'List<dynamic>'' is not a subtype of 'List<Foo>'
}

字符串

jv4diomz

jv4diomz1#

您的问题从这一行开始:

final data = json.decode('[{"bar": 42}]');

字符串
问题是,json.decode被定义为返回dynamic,因此data将被静态分配类型dynamic,这基本上意味着Dart放弃了帮助您处理类型。
这意味着你的程序的其余部分都是dynamic类型的,因为任何对dynamic类型的调用也会导致dynamic类型的结果。
json.decode返回dynamic的原因是因为返回的类型完全取决于您解析的JSON字符串。在你的例子中,你正在解析一个List,所以返回的类型将是List<dynamic>,但是对于其他JSON字符串,我们最终可能会返回以下类型:List<String, dynamic>Stringdoubleint
因此,我们需要在这里帮助Dart并进行类型转换,以防止dynamic发生。在你的情况下,我们会做:

final data = json.decode('[{"bar": 42}]') as List<dynamic>;


这使得data变量的类型为List<dynamic>。这也意味着您稍后对map()的调用是来自Listmap()函数,并且现在知道它如何与泛型一起工作。
注意,我们不能将data类型转换为List<Map<String, int>>,因为无论我们有什么类型的JSON列表,从json.decode返回的列表将始终是List<dynamic>。对于Map也是如此,它也将始终是Map<String, dynamic>
这就是为什么我们想要将这些JSON对象转换为我们自己的数据类的对象的原因之一,就像你在你的例子中尝试做的那样。

相关问题