Деструктуризация

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

Применение pattern matching в языке Dart позволяет выполнить деструктуризацию - разложить некоторую структру данных или объект на отдельные компоненты (данный паттерн еще называется destructuring pattern).

Разложение кортежа

Разложим кортеж на отдельные переменные:

void main() {

  var person = ("Sam", 29);
  var (name, age) = person;

  print("Name: $name");
  print("Age: $age");
}

Здесь кортеж person раскладываем на две переменных - name и age. Эти переменные и их типы указываются также в круглых скобках.

var (String name, int age) = person;

Ключевое слово var фактически объявляет эти переменные. Но переменные также могут быть определены где-то ранее в программе:

void main() {

    var name = "";
    var age = 0;
    var person = ("Sam", 29);
    (name, age) = person;

    print("Name: $name");
    print("Age: $age");
}

Бывает, что нам нужны не все элементы кортежа. В этом случае для ненужных элементов можно передать символ подчеркивания _

void main() {

  var person = ("Sam", 29, "Google");
  var (name, _, company) = person;

  print("Name: $name");
  print("Company: $company");
}

Здесь пропускаем второй элемент кортежа. Подобным образом можно пропустить все элементы, которые нам не нужны:

void main() {

  var person = ("Sam", 29, "Google");
  var (_, age, _) = person;

  print("Age: $age");   // 29
}

Если кортеж имеет именованные элементы, то при разложении их надо сопоставить с переменными:

void main() {


    var person = (name: "Sam", age: 29, company: "Google");
    var (name: personName, age: _, company: personCompany) = person;

    print("Name: $personName");
    print("Company: $personCompany");
}

В данном случае значение элемента name присваивается переменной personName, а значение элемента company - переменной personCompany. Значение элемента age в данном случае не важно, и для него используется символ-заместитель _.

Одним из распространенных сценариев применения разложения кортежа представляет обмен значениями:

void main() {

    int a = 15;
    int b = 50;
    (a, b) = (b, a);
    print("a = $a");    // a = 50
    print("b = $b");    // b = 15
}

В данном случае запись (a, b) = (b, a) фактически означает, что переменная a получает значение переменной b, переменная b - значение переменной a.

Разложение списка

Аналогично разложению кортежа на элементы можно раскладывать и списки:

void main() {

  var numbers = [1, 2, 3];
  var [a, b, c] = numbers;
  print("a=$a  b=$b  c=$c");  // a=1  b=2  c=3
}

С помощью символ-заместителя _ можно пропустить ненужные элементы

void main() {

  var numbers = [1, 2, 3];
  var [a, _, c] = numbers;  // пропускаем второй элемент
  print("a=$a  c=$c");  // a=1  c=3
}

С помощью многоточия ... можно пропустить произвольное количество символов. Например, получим первый, второй и последний элементы списка:

void main() {

  var numbers = [1, 2, 3, 4, 5, 6, 7, 8];
  var [a, b, ..., c] = numbers;
  print("a=$a  b=$b  c=$c");  // a=1  b=2  c=8
}

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

void main() {

  var numbers = [1, 2, 3, 4, 5, 6, 7, 8];
  var [a, b, ...] = numbers;  // получаем два первых элемента
  var [..., c, d] = numbers;  // получаем два последних элемента
  print("a=$a  b=$b  c=$c  d=$d");  // a=1  b=2  c=7  d=8
}

Разложение объектов

Dart также позволяет раскладывать объекты классов на отдельные значения. Например:

void main() {
    
    var tom = Person("Tom", 38);
    var Person(name: userName, age: userAge) = tom;
    print(userName);  // Tom
    print(userAge);   // 38
}

class Person{

  String name;
  int age;
  Person(this.name, this.age);
}

Здесь объект класса Person расскладывается на две переменных - userName и userAge. При разложении сначала указываем имя класса и в скобках сопоставляем свойства класса с переменными

var Person(name: userName, age: userAge) = tom;
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850