Паттерны списков позволяют сопоставлять выражения со списками. Например, полное совпадение со списком:
void main() { print(getNumber([1, 2, 3, 4, 5])); // 1 print(getNumber([1, 2])); // 3 print(getNumber([])); // 4 print(getNumber([1, 2, 5])); // 5 } int getNumber(List<int> values) { switch(values) { case [1, 2, 3, 4, 5]: return 1; case [1, 2, 3]: return 2; case [1, 2]: return 3; case []: return 4; default: return 5; } }
С помощью паттерна _ можно обозначить одиночный элемент, который имеет любое значение. Например, паттерн [2, _, 5] соответствует любому списку из трех элементов, в котором между 2 и 5 располагается произвольное значение. А паттерн [_, _] соответствует любому списку из двух произвольных элементов. Несколько примеров:
void main() { print(getNumber([2, 3, 5])); // 1 print(getNumber([2, 4, 6])); // 2 print(getNumber([1, 2, 5])); // 3 print(getNumber([1, 2, 3])); // 4 print(getNumber([])); // 5 } int getNumber(List<int> values) { switch(values) { case [2, _, 5]: return 1; case [2, _, _]: return 2; case [_, _, 5]: return 3; case [_, _, _]: return 4; case _: return 5; } }
Выражение case _
фактически аналогично выражению default
, которое задает вариант по умолчанию, если предыдущие выражения case не соответствуют сравниваемому значению.
Для передачи произвольного количества элементов списка применяется slice-паттерн ... (три точки). Например, паттерн [1, 2, ..., 5]
соответствует списку, в который начинается на 1, за которым идет 2, а последний элемент - 5. При этом между 2 и 5 может располагаться произвольное количество произвольных целых
чисел. То есть паттерн [1, 2, ..., 5]
будет соответствовать таким спискам как
[1, 2, 3, 4, 5] [1, 2, 5] [1, 2, 66, 77, 88, 5]
С помощью паттерна ... можно задавать произвольное количество элементов как в начале, так и в конце списка. Например, паттерн [2,...]
представляет список, который начинается на 2. А паттерн [..., 5]
представляет список, который заканчивается элементом 5.
Паттерн [...]
представляет массив, который содержит произвольное количество элементов. Например:
void main() { print(getNumber([2, 5])); // 1 print(getNumber([2, 3, 4, 5])); // 1 print(getNumber([2])); // 2 print(getNumber([2, 3, 4])); // 2 print(getNumber([3, 4, 5])); // 3 print(getNumber([5])); // 3 print(getNumber([])); // 4 print(getNumber([1])); // 4 print(getNumber([1, 2, 3])); // 4 } int getNumber(List<int> values) { switch(values) { case [2, ..., 5]: return 1; // если первый элемент - 2, а последний - 5 case [2,...]: return 2; // если первый элемент - 2 case [..., 5]: return 3; // если последний элемент - 5 case [...]: return 4; // произвольное количество элементов } }
slice-паттерн можно сочетать с символов подстановки _, например:
int getNumber(List<int> values) { switch(values) { case [_, ..., _]: return 1; case [...]: return 2; } }
В данном случае паттерн [_, ..., _]
предполагает список, который состоит как минимум из двух произвольных элементов, и между первым и последним элементром может находиться произвольное количество других элементов:
void main() { print(getNumber([1, 2, 3, 4])); // 1 print(getNumber([1, 2, 3])); // 1 print(getNumber([1, 2])); // 1 print(getNumber([1])); // 2 print(getNumber([])); // 2 } int getNumber(List<int> values) { switch(values) { case [_, ..., _]: return 1; case [...]: return 2; } }
Паттерны кортежей позволяют сравнивать значения кортежей. Например, передадим в конструкцию switch кортеж с названием языка и времени дня и в зависимости от переданных данных возвратим определенное сообщение:
void main() { print(createMessage(("english", "morning"))); // Good morning print(createMessage(("german", "evening"))); // Guten Abend print(createMessage(("undefined", ""))); // Hello World } String createMessage((String, String) data) { switch(data) { case ("english", "morning"): return "Good morning"; case ("english", "evening"): return "Good evening"; case ("german", "morning"): return "Guten Morgen"; case ("german", "evening"): return "Guten Abend"; default: return "Hello World"; } }
Здесь функция createMessage принимает кортеж record из двух элементов String. В конструкции switch сравниваем этот кортеж с некоторыми данными и в зависимости от результата сравнения возвращаем ту или иную строку.
Также в случае с кортежами, как и в случае со списками, можно применять паттерн _
, который заменяет произвольный элемент кортежа:
void main() { print(createMessage(("english", "morning"))); // Good morning print(createMessage(("english", "evening"))); // Hello print(createMessage(("undefined", ""))); // Hello World } String createMessage((String, String) data) { switch(data) { case ("english", "morning"): return "Good morning"; case ("english", _): // второй элемент не важен return "Hello"; case _: return "Hello World"; } }