Основы Dart 2.x (Generics)

14.09.2019
This article was written for an older Flutter version and is being updated. Some code may not compile on the current version.

Generics - параметризованные типы, дженерики или обобщения позволяют программе уйти от жесткой привязки к определенным типам, определить функционал так, чтобы он мог использовать данные любых типов и обеспечить их безопасность. Так же обобщения снижают повторяемость кода, дают вам возможность предоставить единый интерфейс и реализацию для многих типов. Пример:

Если вы хотите, чтобы список содержал только строки (string), вы можете объявить его как List<String> (список строк). Таким образом, при присвоение не string списка возникнет ошибка.
var names = List();
names.addAll(['Ryzen', 'Core', 'Pentium', 'Duron']);
names.add(42); // Ошибка
  • Так же с помощью выражения <T> мы можем указать, что объявляемый нами тип (класс например) типизирован неопределенным типом T (универсальным параметром) - где Т это тип вашего класса, вместо Т будет подставляться конкретный тип (это происходит динамически).

Пример:

 void main (){

    Processor ryzen = Processor(7, "AMD");
    Processor core = Processor("i7", "Intel");
}
 class Processor{
    T model;
    String company;
    Processor(this.model, this.company);
}

Разберем подробнее: У нас есть типизированный класс Processor c определенным типом T (универсальным параметром), дальше мы можем использовать наш символ T как обычный тип, например определять переменные этого типа, что мы и сделали если посмотреть на поле T model нашего класса. Далее, при выполнении нашей программы вместо Т будет динамически подставляться конкретный тип на основе входящих данных. То есть поле model будет иметь тип int когда мы передаем в конструкторе число 7 модели процессора ryzen и тип string когда мы передаем значение "i7" в модели процессора core.

  • Так же стоит уточнить что в место символа Т в верхнем регистре, можно подставить абсолютно любой, например Х или Е , но обычно используется символ Т от английского слова Type (тип) . Generics методы Таким же образом мы можем создать типизированные методы:
T first(List ts) {
  T tmp = ts[0];
  return tmp;
}

Здесь параметр общего типа для first<Т> позволяет использовать аргумент типа Т в нескольких местах:

  • Возвращаемый универсальный тип Т нашего метода.
  • Аргумент метода List<T>.
  • Локальная переменная метода T tmp . Используйте "дженерики", чтобы получить максимально широкие возможности многократного использования кода, для обеспечения безопасности типов и повышения производительности.