Pattern

1. Логический шаблон ИЛИ A || B

Совпадает с любым подшаблоном; все ветви должны определять полностью одинаковый набор переменных.

enum Color { red, yellow, blue, green }
void main() {
  Color c = Color.red;
  bool primary = switch(c) {
    Color.red || Color.yellow || Color.blue => true,
    _ => false
  };
  print(primary); // true
}Code language: Dart (dart)

2. Логический шаблон И A && B

Оба подшаблона должны совпадать одновременно; подшаблоны не могут привязывать переменные с одинаковым именем.

void main() {
  switch((2, 3)) {
    // Ошибка: оба подшаблона привязывают переменную b, конфликт имен
    // case (var a, var b) && (var b, var c): print("ok");
    case (var a, var b) && (>1, <5):
      print("a=$a,b=$b"); // a=2,b=3
  }
}Code language: Dart (dart)

Запись (>1, <5) означает, что первое число должно быть больше 1, а второе меньше 5.

3. Относительный шаблон < > <= >= == !=

Используется для проверки числовых диапазонов, часто сочетается с && для ограничения границ значений

String asciiCharType(int charCode) {
  const space = 32, zero = 48, nine = 57;
  return switch(charCode) {
    < space => "Управляющий символ",
    == space => "Пробел",
    > space && < zero => "Знак препинания",
    >= zero && <= nine => "Цифра",
    _ => "Другое"
  };
}
void main() {
  print(asciiCharType(50)); // Цифра
  print(asciiCharType(33)); // Знак препинания
}Code language: Dart (dart)

В данном примере используется код ASCII для классификации управляющих символов, цифр и знаков. Правила проверки charCode в switch: меньше 32 — управляющий символ, равно 32 — пробел, между 32 и 48 — знаки препинания, от 48 до 57 включительно — цифры, остальное относится к категории «другое».

4. Шаблон принудительного преобразования типа sub as Type

Выполняет явное преобразование типа во время деструктуризации; при несоответствии типов выбрасывает исключение во время выполнения

void main() {
  (num, Object) rec = (10, "hello");
  var (i as int, s as String) = rec;
  print(i + 5); // 15
  print(s.toUpperCase()); // HELLO
}Code language: Dart (dart)

В примере запись rec разбивается на переменные i и s. Если первый элемент не целое число, а второй не строка — возникнет runtime-исключение.

Ниже приведён пример с ошибкой:

void main() {
  (num, Object) rec = (9.3, "hello");
  var (i as int, s as String) = rec;
  print(i + 5); // 15
  print(s.toUpperCase()); // HELLO
}Code language: Dart (dart)
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
Unhandled exception:
type 'double' is not a subtype of type 'int' in type cast
#0      main (file:///D:/dartdemo/firstdart/bin/firstdart.dart:3:10)
#1      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:314:19)
#2      _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:193:12)Code language: PHP (php)

5. Шаблон проверки на null sub?

Совпадает только с непустым значением; внутренние переменные автоматически повышаются до неподдерживающих null типов. При значении null совпадение не происходит, исключений не генерируется.

void main() {
  String? str = "test";
  switch(str) {
    case var s?:
      print(s.length); // s — строка без null, вывод 4
    case null:
      print("Пустое значение");
  }
}Code language: Dart (dart)

6. Шаблон утверждения не-null sub!

Совпадает только с непустым значением; если значение равно null — сразу выбрасывает runtime-исключение

void main() {
  List<String?> row = ["user", "bob"];
  switch(row) {
    case ["user", var name!]:
      print(name); // name — строка без null
  }

  // Использование при деструктуризации переменных
  (int?, int?) pos = (2, 3);
  var (x!, y!) = pos;
  print(x + y);
}Code language: Dart (dart)

Разбор записи var name!

  • var nameПеременный шаблон — ключевое слово var объявляет новую локальную переменную name и привязывает подходящее значение при совпадении;
  • !Постфиксный шаблон утверждения не-null — требует, чтобы значение не было равным null; при null возникает ошибка во время выполнения.

Общее значение: var name! создаёт новую переменную name и одновременно гарантирует, что её значение не может быть null.

7. Константный шаблон

Литералы, именованные константы, конструкторы const и коллекции const относятся к константным шаблонам; совпадение возникает при полном равенстве значений

Поддерживаемые типы: числа, строки, булевы значения, именованные константы, объекты / списки с модификатором const

void main() {
  const target = 10;
  int num = 10;
  switch(num) {
    case 1: print("Один");
    case target: print("Совпадает с константой 10");
    case const [1,2]: print("Константный список");
    default: print("Другое");
  }
}Code language: Dart (dart)

Результат выполнения программы

Совпадает с константой 10

8. Переменный шаблон var x / int x / final x

При успешном совпадении привязывает новую локальную переменную; аннотация типа одновременно проверяет тип значения

void main() {
  switch((99, "dart")) {
    case (int a, String b):
      print("$a $b"); // 99 dart
    case (int a, int b):
      print("Два числовых значения");
  }
}Code language: Dart (dart)

9. Идентификаторный шаблон

Поведение разделяется на три контекста:

  1. Контекст объявления var (a,b):Создаёт новые переменные
  2. Контекст присваивания (a,b) = val:Перезаписывает существующие переменные
  3. Контекст сопоставления switch:Обрабатывается как константа (исключение — _)
void main() {
  const c = 5;
  int val = 2;
  switch(val) {
    case c: print("Совпадает с константой c");
    default: print("Совпадения нет"); // Выполняется эта строка
  }
}
Code language: Dart (dart)

10. Скобочный шаблон (subPattern)

Изменяет приоритет операторов шаблона для разделения порядка вычисления || и &&

void main() {
  bool x = true, y = true, z = false;
  bool test = switch(true) {
    (x || y) && z => true,
    _ => false
  };
  print(test); // false
}
Code language: Dart (dart)

11. Шаблон списка

Совпадает с объектами List и разбирает элементы по позиции; поддерживает оператор rest ... для захвата любого количества оставшихся элементов

1. Базовое сопоставление списка
void main() {
  const a = "a", b = "b";
  var arr = ["a", "b"];
  switch(arr) {
    case [a, b]: print("Совпадение найдено");
    default: print("Совпадения нет");
  }
}Code language: Dart (dart)
2. Захват остаточных элементов через rest
void main() {
  var [a, b, ...rest, c, d] = [1,2,3,4,5,6,7];
  print("$a $b $rest $c $d"); // 1 2 [3, 4, 5] 6 7
}
Code language: Dart (dart)
D:\dartdemo\firstdart>dart run
Building package executable...
Built firstdart:firstdart.
1 2 [3, 4, 5] 6 7Code language: CSS (css)

12. Шаблон Map {"key": subP}

Совпадает с объектами Map и проверяет только указанные ключи; при отсутствии нужного ключа генерируется StateError, лишние неупомянутые ключи игнорируются

void main() {
  var data = {"user": ["Lily", 13]};
  if(data case {"user": [String name, int age]}) {
    print("$name $age"); //Lily 13
  }
}Code language: JavaScript (javascript)

13. Шаблон записей (Record)

Два варианта: позиционная запись (p1,p2), именованная запись (k:p1,k2:p2)

Поддерживается сокращённая запись :var для исключения повторяющихся имён полей

void main() {
  // Деструктуризация позиционной записи
  var (name, age) = ("Doug", 25);
  // Сокращённая деструктуризация именованных полей
  final (:name, :age) = (name: "Tom", age: 18);
}
Code language: JavaScript (javascript)

14. Шаблон объекта Class(prop: p)

Совпадает с объектами указанного типа и разбирает свойства геттеров; поддерживается сокращение :var

class Point {
  final int x, y;
  Point(this.x, this.y);
}

void main() {
  Point p = Point(10, 20);
  var Point(:x, :y) = p;
  print("$x $y");
}
Code language: JavaScript (javascript)

15. Шаблон подстановочного символа _

Совпадает с любым значением без привязки переменной; используется как заполнитель или только для проверки типа без извлечения значения

void main() {
  var arr = [1,2,3];
  var [_, mid, _] = arr;
  print(mid); // 2

  switch((10, "abc")) {
    case (int _, String _):
      print("Типовое совпадение успешно");
  }
}Code language: JavaScript (javascript)

Pattern

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

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