Pattern matching

Сопоставление с константами и литералами

Последнее обновление: 28.07.2023

Начиная с версии 3.0 в Dart была добавлена такая функциональность как pattern matching или сопоставление шаблонов. Шаблон представляет форму набора значений, которые могут сопоставляться с фактическими значениями.

Самый простой тип сопоставления шаблонов представляет сопоставление с литералами в конструкции switch:

void main() {
    int num = 2;
    switch(num){
                 
        case 1: 
            print("num = 1");
        case 2: 
            print("num = 2");
        case 3: 
            print("num = 3");
        default:
            print("num is undefined");
    }
}

Выражение case определяет шаблон, с которым сопосбавляется некоторое значение. Здесь значение переменной num сопоставляется с рядом константных значений, представленных целочисленными литералами 1, 2, 3. Если сопоставление завершается удачно (переменная num равна определенному значению), то выполняется код из соответствующего блока case.

Но pattern matching этим неограничивается. Рассмотрим другие типы pattern matching.

Сопоставление с константами

Подобно тому, как сопоставляем некоторое значение с литералами, также можно сопоставлять с константами:

void main() {
    int num = 2;
    const int a = 1, b =2, c = 3;

    switch(num){   
        case a: 
            print("num = a");
        case b: 
            print("num = b");
        case c: 
            print("num = c");
        default:
            print("num is undefined");
    }
}

Здесь значение переменной num сопоставляется с константами a, b, c. Стоит отметить, что a, b и c в данном случае должны быть именно константами.

Возвращение результата

Отличительной особенностью конструкции switch является то, что она позволяет возвращать значения. Раньше можно было использовать оператор return для возвращения из блока case определенного значения. Например:

void main() {
    
    print(createMessage("english"));    // Hello
    print(createMessage("russian"));    // Привет
    print(createMessage("spanish"));    // Hello World
}

String createMessage(String language)
{
    switch(language)
    {
        case "english": 
            return "Hello";
        case "russian":
            return "Привет";
        case "german":
            return "Hallo";
        default: return "Hello World";
    };
}

Здесь функция createMessage принимает название языка и передает его в конструкцию switch. В конструкции switch значение language сопоставляется с рядом значений, и в зависимости от результата сопоставления с помощью оператора return в каждом блоке case возвращается та или иная строка.

Хотя этот пример прекрасно работает, но сама конструкция switch выглядит несколько громоздко. И Dart позволяет ее сократить:

void main() {
    
    print(createMessage("english"));    // Hello
    print(createMessage("russian"));    // Привет
    print(createMessage("spanish"));    // Hello World
}

String createMessage(String language)
{
    return switch(language)
    {
        "english" => "Hello",
        "russian" => "Привет",
        "german" => "Hallo",
        _ => "Hello World"
    };
}

Теперь оператор return указывается один раз - перед конструкцией switch. Внутри конструкции операторы case больше не используются - вместо них просто указываются шаблоны, с которыми сопоставляется значение language. В данном случае в качестве шаблонов выступают строковые литералы. Для определения возвращаемого значения после шблона идет оператор =>, после которого указывается возвращаемое значение:

"english" => "Hello",

При этом отдельные блоки с шаблонами отделены друг от друга запятой (а не точкой с запятой).

Также стоит отметить последний шаблон

_ => "Hello World"

Паттерн _ применяется для определения шаблона для всех остальных случаев (аналогично блоку default).

Таким образом, код стал немного компактнее и проще.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850