Паттерн словарей позволяет сравнить словари с некоторыми шаблонами. Эти шаблоны могут определять шаблон для значений ключей словаря. Например:
void main() { var admin = {"name": "admin", "email": "admin@hmail.com"}; var tom = {"name": "Tom", "email": "tom@hmail.com"}; var bob = {"email": "bob@hmail.com"}; print(createMessage(admin)); // Hello Admin! print(createMessage(tom)); // Hi Tom print(createMessage(bob)); // Hello World } String createMessage(Map data) { return switch(data) { {"name": "admin"} => "Hello Admin!", // если name = "admin" {"name": var name} => "Hi $name", // если есть ключ name _ => "Hello World" // в остальных случаях }; }
Здесь функция createMessage получает словарь data и передает его в конструкцию switch, которая сравнивает словаорь с рядом паттернов. Первый паттерн говорит, что в словаре должен быть ключ "name" и он должен быть равен "admin":
{"name": "admin"} => "Hello Admin!", // если name = "admin"
Второй паттерн говорит, что в словаре в принципе должен быть ключ "name", но чему он равен - не важно. Значение этого ключа получаем в переменную name, которая затем применяется для формирования строки:
{"name": var name} => "Hi $name", // если есть ключ name
Третий паттерн применяется во всех остальных случаях (например, когда в словаре нет ключа "name").
Паттерн объектов позволяет сопоставить свойства объекта с некоторыми шаблонами. Например:
void main() { var tom = Person("Tom", 38); var tomas = Person("Tom", 17); var bob = Person("Bob", 42); print(createMessage(tom)); // Hello Tom print(createMessage(tomas)); // Hello Tomas print(createMessage(bob)); // Hi Bob } String createMessage(Person person) { return switch(person) { Person(name:"Tom", age: >18) => "Hello Tom", // name = "Tom" и age > 18 Person(name:"Tom") => "Hello Tomas", // name = "Tom" и age <= 18 Person(name: var pname) => "Hi $pname" // в остальных случаях }; } class Person{ String name; int age; Person(this.name, this.age); }
Здесь в функции createMessage объект класса Person, который имеют два свойства: name и age, сопсотавляется с рядом шаблонов. Первый шаблон указывает, что свойство "name" должно быть равно "Tom", а свойство age должно быть больше 18:
Person(name:"Tom", age: >18) => "Hello Tom"
То есть фактически паттерн объектов предполагает применение к его свойствам других паттернов. Так, к свойству name применяется паттерн констант, а к свойству age - реляционный паттерн.
Второй паттерн более общий и применяется, если свойство name равно "Tom"
Person(name:"Tom") => "Hello Tomas",
Третий паттерн применяется во всех остальных случаях - он просто извлекает значение свойства name в переменную username
Person(name: var pname) => "Hi $pname"
Подобным образом можно сопоставлять произвольные достпуные свойства объектов, в том числе встроенных классов. Например, проверим длину строки:
void main() { print(checkPassword("hello")); // Invalid password print(checkPassword("hello wo")); // Weak password print(checkPassword("hello world")); // Strong password } String checkPassword(String password){ return switch(password){ String(length:>10) => "Strong password", String(length:>6) => "Weak password", _ => "Invalid password" }; }
Здесь проверяем, больше ли длина строки определенного значения, и в зависимости от результатов проверки возвращаем то или иное сообщение.