Pattern Matching
dartВозможность сопоставлять значение с шаблоном. Не просто проверка на строгое равенство по значению, но и проверка соответствия по форме.
Применяется в основном с switch case
и if case
.
При простом сравнении значений, может показаться что ничего необычного, просто проверка на равенство как в JavaScript.
// Привычное по JavaScript поведение switch, когда значение == значению кейса
switch (number) {
// Константный паттерн, если number == 42
case 42:
print('Answer 42');
}
Но возможно и более сложное сопоставление, которое рекурсивно сопоставляет сложные структуры:
var obj1 = ['a', 'b'];
switch (obj1) {
// Не этот кейс. Оба элемента строки, но порядок другой.
case ['b', 'a']:
print('Case 1');
// Не этот кейс. Первый элемент подходит, а второй не строка
case ['a', 42]:
print('Case 2');
// Выполнение будет данного кейса. obj список с двумя строками, и именно в таком порядке
case ['a', 'b']:
print('Case 3'); // Case 3
}
Сопоставляемые части можно опускать с помощью _
и ...
:
var obj2 = ['a', 'b'];
switch (obj2) {
// С помощью заполнителя _ (wildcard) мы игнорируем первое значение в списке, говорим что оно не важно.
// Выполниться этот кейс, так как второе значение подходит
case [_, 'b']:
print('Case 1'); // Case 1
// Подходит и этот кейс, но switch выполняет первый подходящий по порядку
case ['a', 'b']:
print('Case 2');
}
Проверять можно не только соответствие конкретным значениям в структурах, но и типам и условиям:
var obj3 = const ['a', 42];
switch (obj3) {
// Выполниться этот кейс, так как первое значение строка, а вторая целое число,
case [String _, int _]:
print('Case 1'); // Case 1
// Этот кейс тоже подходит, первое значение строка, а второе 7 или 42. Но первый кейс подошёл первым
case [String _, 7 || 42]:
print('Case 2');
}
С объектами:
switch (shape) {
// Проверяем что тип объекта соответствует Rect, а затем свойства объекта.
case Rect(width: var w, height: var h): // ...
}