在我的问题中Dart 2.X List.cast() 不组合 https://stackoverflow.com/questions/49539879/dart-2-x-list-cast-does-not-compose答案需要转换List<dynamic>
to a List<String>
像这样:
List<String> ls = (json['data'] as List).cast<String>().map((s) => s.toUpperCase()).toList();
我在其他语言中的经验让我首先写下这个:
List<String> ls = (json['data'] as List<String>).map((s) => s.toUpperCase()).toList();
请注意,这可以编译,但在 Dart 2 中运行时会失败。
为什么 Dart 类型转换为List
需要一个函数as List).cast<String>()
而不是简单地使用 Dartas
“类型转换运算符”,例如as List<String>
?
- - 编辑 - -
我正在使用最新的 Dart 2.0.0-dev.43.0 并获得不一致的运行时行为as
类型转换/断言。难道不是.cast<>()
函数创建一个新的可迭代对象,与.map()
?将我的代码更改为这样有效:
List<String> ls = (json['data'] as List).map((s) => (s as String).toUpperCase()).toList();
这似乎利用了第一个演员List
is a List<dynamic>
。就这样.map
函数参数也是一个dynamic
.
我上面的第二个例子是as List<String>
在我们的代码中的某些地方有效,但在其他地方则无效。请注意,IntelliJ 正确推断了上述所有示例中的类型 - 这是发生故障的运行时。我猜测不一致的行为是由于 Dart 2.x 仍在开发中。
---- 第二次编辑 ----
以下是我的类构造函数之一中的测试用例:
Map<String, dynamic> json = { "data": ["a", "b", "c"] };
//List<String> origBroken = json["data"].map( (s) => s.toUpperCase() ).toList();
// Sometimes works - sometimes gives "Ignoring cast fail from JSArray to List<String>" at runtime!!!
List<String> wonky = (json["data"] as List<String>).map( (s) => s.toUpperCase() ).toList();
print("Wonky $wonky");
List<String> fix1 = (json["data"] as List).cast<String>().map( (s) => s.toUpperCase() ).toList();
List<String> fix2 = (json["data"] as List).map( (s) => (s as String).toUpperCase() ).toList();
List<String> explicit2 = (json["data"] as List<dynamic>).map( (dynamic s) => (s as String).toUpperCase() ).toList();
// From accepted answer of the linked question - compile error because .cast() doesn't take parameters
// error: Too many positional arguments: 0 expected, but 1 found.
//List<String> notBroken = (json['data'] as List).cast<String>((s) => s.toUpperCase()).toList();
List<String> notBrokenFixed = (json['data'] as List<String>).cast<String>().map((String s) => s.toUpperCase()).toList();
问题是警告Ignoring cast fail from JSArray to List<String>
有时由wonky
任务。当我说有时是因为当我对使用包含此代码的库的主应用程序进行更改时,它会发生不可预测的变化 - 而不对此类甚至库进行更改。
当我写上面的第一个编辑时,wonky
没工作。我现在又试了一次,它可以工作了。我没有更改此库中的任何代码 - 我一直在依赖此代码库的主应用程序中工作。
一些背景知识,这是一个从 Angular/Typescript 转换而来的多库项目。这些测试用例基于我们将 JSON 反序列化为 Dart 类的处理。我们使用类构造函数初始值设定项将 JSON(动态)字符串映射到各种数据结构,例如枚举、Option 和 Either(来自 dartz)。
几周前,运行时警告开始发生,我相信是因为重大更改:--preview-dart-2 默认打开 https://groups.google.com/forum/#!topic/flutter-dev/H8dDhWg_c8I。
我知道这个警告很快就会变成错误。因此,我将警告追溯到这些从 JSON 动态数据映射的转换(是的,动态数据是 Dart 中的边缘情况,但这就是dart:convert
提供)。
我们正在 Mac 上使用 DDC 进行开发,其中包含最新的 Dart 2.0.0-dev.43.0、Angular 5.0.0-alpha+8、build_runner 0.8.0、IntelliJ 2018.1,并在 Chrome 65.0.3325.181 上运行。
---- 最终编辑 ----
此问题背后的当前开发构建/运行时存在不稳定。不,我没有可重现的例子。更改和重建我们的主应用程序将导致未修改的库依赖项中的此代码有时会发出运行时警告Ignoring cast fail from JSArray to List<String>
.
这个问题原始部分的可疑代码(也wonky
above)
List<String> ls = (json['data'] as List<String>).map((s) => s.toUpperCase()).toList();
将动态 JSON 数据转换为List<String>
。类型受到完全约束,Dart 分析器/IntelliJ 推断s
to be Static type: String
.
有时出现的运行时警告及相关使用解答.cast()
是什么导致了这个问题。这时我会相信分析器并忽略运行时警告。