Dart 2.X List.cast() 不组合

Ric*_*son 5 dart

即将发布的 Dart 2.X 版本需要强类型。在处理 JSON 数据时,我们现在必须将dynamic类型转换为适当的 Dart 类型(不是问题)。一个相关的问题Ignoring cast fail from JSArray to List<String>提供了使用该.cast<String>()函数的答案。最近的一组消息也有同样的说法: Breaking Change: --preview-dart-2 enabled by default

问题是该.cast()函数似乎没有组合。使用 DDC 编译并在 Chrome 浏览器中运行时的原始代码:

Map<String, dynamic> json = { "data": ["a", "b", "c"] };
List<String> origBroken = json["data"].map( (s) => s.toUpperCase() ).toList();
Run Code Online (Sandbox Code Playgroud)

现在收到运行时警告(很快就会出错)

Ignoring cast fail from JSArray to List<String>
Run Code Online (Sandbox Code Playgroud)

所以我.cast<String>()按照文档和相关链接的建议添加,但仍然收到警告:

List<String> docFixBroken = json["data"].cast<String>().map( (s) => s.toUpperCase() ).toList();
List<String> alsoBroken = List.from( (json["data"] as List).cast<String>() ).map( (s) => s.toUpperCase() ).toList();
Run Code Online (Sandbox Code Playgroud)

不发出警告的代码需要一个临时变量(并且似乎也可以跳过显式转换):

List<String> temp = json["data"];
List<String> works = temp.map( (s) => s.toUpperCase() ).toList();
Run Code Online (Sandbox Code Playgroud)

那么如何将 cast 和 map 编写为单个组合表达式呢?我需要它作为单个表达式的原因是这个表达式正在初始化列表中用于设置最终类变量。

mat*_*rey 7

我写了Ignoring cast fail from JSArray to List<String>,所以让我也在这里尝试帮助!

所以我.cast<String>()按照文档和相关链接的建议添加,但仍然收到警告:

List<String> docFixBroken = json["data"].cast<String>().map( (s) => s.toUpperCase() ).toList();
List<String> alsoBroken = List.from( (json["data"] as List).cast<String>() ).map( (s) => s.toUpperCase() ).toList();
Run Code Online (Sandbox Code Playgroud)

不幸的是,List.from由于工厂构造函数 ( https://github.com/dart-lang/sdk/issues/26391 )缺少泛型类型,因此不会保留类型信息。在此之前,您应该/可以使用.toList()

(json['data'] as List).toList()
Run Code Online (Sandbox Code Playgroud)

所以,重写你的例子:

List<String> docFixBroken = json["data"].cast<String>().map( (s) => s.toUpperCase() ).toList();
List<String> alsoBroken = List.from( (json["data"] as List).cast<String>() ).map( (s) => s.toUpperCase() ).toList();
Run Code Online (Sandbox Code Playgroud)

可以写成:

List<String> notBroken = (json['data'] as List).cast<String>((s) => s.toUpperCase()).toList();
Run Code Online (Sandbox Code Playgroud)

希望有帮助!