Операторы разворота Dart

Операторы разворота Spread operators ... и ...?

Вычисляет выражение коллекции, распаковывает все элементы внутри коллекции и извлекает их, после чего вставляет в другой литерал коллекции (список, Set, Map)

Не относятся к операторным выражениям: ... и ...? не являются операторами в классическом понимании, это синтаксический сахар

Существует два варианта

...collection: обычный разворот. Требуется, чтобы коллекция никогда не была равна null; передача значения null сразу вызывает ошибку

...?collection: безопасный разворот с проверкой на null. Если коллекция равна null, она игнорируется без выброса исключения

Официальные примеры легко помогут разобраться в работе конструкции

void main() {
  final list1 = [1, 2, 3];
  final list2 = [0, ...list1, 4, 5];
  print(list2); // [0, 1, 2, 3, 4, 5]

  // Безопасный разворот для null
  List<int>? maybeList;
  final safeList = [10, ...?maybeList, 20];
  print(safeList); // [10, 20], ошибки не возникнут, если maybeList равен null
}Code language: Dart (dart)

В примере выше используются две коллекции: первая содержит три элемента 1, 2, 3. Во второй коллекции первая вставляется после нуля, затем добавляются числа 4 и 5, итоговый результат — [0, 1, 2, 3, 4, 5]

Второй пример также выполняет вставку, но переменная maybeList имеет значение null и используется безопасный разворот. Поэтому элементы не добавляются, результат не меняется, ошибок не появляется

Пример с Set

void main() {
	final set1 = {1, 2};
	final set2 = {3, ...set1, 4};
	print(set2); // {3, 1, 2, 4}
}Code language: PHP (php)

Пример с Map

void main() {
	final map1 = {'a': 1, 'b': 2};
	final map2 = {'c': 3, ...map1, 'd': 4};
	print(map2); // {c: 3, a: 1, b: 2, d: 4}
}Code language: PHP (php)

Важные замечания

Конструкцию ... нельзя использовать отдельно за пределами скобок [] и фигурных скобок {}

void main() {
    final list1 = [1, 2, 3];
	var arr = ...list; // Синтаксическая ошибка, можно записывать только внутри литерала коллекции
}Code language: PHP (php)
D:\dartdemo\firstdart>dart run
Building package executable...
Failed to build firstdart:firstdart:
bin/firstdart.dart:3:12: Error: Expected an identifier, but got '...'.
Try inserting an identifier before '...'.
        var arr = ...list; // Синтаксическая ошибка, можно записывать только внутри литерала коллекции
                  ^^^
bin/firstdart.dart:3:12: Error: Expected ';' after this.
        var arr = ...list; // Синтаксическая ошибка, можно записывать только внутри литерала коллекции
                  ^^^
bin/firstdart.dart:3:15: Error: Undefined name 'list'.
        var arr = ...list; // Синтаксическая ошибка, можно записывать только внутри литерала коллекцииCode language: PHP (php)

Прямой разворот значения null через ... вызывает ошибку во время выполнения. Если переменная может быть null, обязательно используйте ...?

void main() {
	List<int>? list = null;
	var res = [...list]; // Возникает ошибка
	var resSafe = [...?list]; // Работает корректно
}Code language: PHP (php)
D:\dartdemo\firstdart>dart run
Building package executable...
Failed to build firstdart:firstdart:
bin/firstdart.dart:3:16: Error: An expression whose value can be 'null' must be null-checked before it can be dereferenced.
        var res = [...list]; // Возникает ошибкаCode language: PHP (php)

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *