Dart 2.X List.cast() does not compose

The upcoming Dart 2.X release requires strong typing. When working with JSON data we must now cast dynamic types to an appropriate Dart type (not a problem). A related question Ignoring cast fail from JSArray to List; provides the answer to use the .cast<String>() функция. Also a recent group messages says the same: Breaking Change: --preview-dart-2 turned on by default.

Проблема в том, что .cast() function doesn't seem to compose. This original code when compiled using DDC and run in the Chrome browser:

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

Now receives the runtime warning (which will soon be an error)

Ignoring cast fail from JSArray to List<String>

So I add the .cast<String>() as the documentation and related link suggest and still receive the warning:

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();

The code that doesn't give the warning requires a temporary variable (and also seems to be able to skip the explicit cast):

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

So how can I write the cast and map as a single composed expression? The reason I need it as a single expression is that this expression is being used in an initializer list to set a final class variable.

1 ответ

Решение

Я написал " Игнорирование сбоя приведения" из JSArray в List;, поэтому позвольте мне попытаться помочь и здесь!

Поэтому я добавляю .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();

К несчастью, List.from не сохраняет информацию о типе из-за отсутствия универсальных типов для конструкторов фабрики ( https://github.com/dart-lang/sdk/issues/26391). До тех пор, вы должны / могли бы использовать .toList() вместо:

(json['data'] as List).toList()

Итак, переписываем ваши примеры:

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();

Может быть написано как:

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

Надеюсь, это поможет!

Другие вопросы по тегам