Ответ
Generics (обобщённые типы) — это механизм Dart для создания классов, функций и интерфейсов, которые могут работать с разными типами данных, сохраняя при этом безопасность типов на этапе компиляции. Они позволяют писать универсальный и переиспользуемый код.
Основная идея: Заменить конкретный тип параметром (например, T, E, K, V), который будет указан позже.
Пример универсального класса Box:
class Box<T> {
final T contents;
Box(this.contents);
T getItem() => contents;
}
void main() {
var intBox = Box<int>(42); // T заменяется на int
var stringBox = Box<String>('Hello'); // T заменяется на String
// stringBox.getItem() + 5; // ОШИБКА КОМПИЛЯЦИИ: String + int
}
Ограничение типов с помощью extends:
// Класс работает только с типами, являющимися подтипами num (int, double)
class NumericContainer<T extends num> {
List<T> _values = [];
void add(T value) => _values.add(value);
T sum() => _values.fold(0 as T, (a, b) => (a + b) as T);
}
void main() {
var container = NumericContainer<int>();
container.add(10);
container.add(20);
print(container.sum()); // 30
// var badContainer = NumericContainer<String>(); // Ошибка компиляции
}
Где это используется в Dart/Flutter:
- Коллекции:
List<E>,Map<K, V>,Set<E>. - Асинхронность:
Future<T>,Stream<T>. - Виджеты:
ValueListenableBuilder<T>,FutureBuilder<T>. - State Management:
Provider<T>,Riverpod'sProvider<T>.
Ответ 18+ 🔞
Э, слушай, вот тебе история про дженерики в Dart. Представь, что ты пишешь код, и тебе нужно, чтобы одна и та же штука работала и с числами, и со строками, и с чем угодно, но при этом чтобы компилятор не орал на тебя, как сумасшедший, когда ты попробуешь сложить строку с числом. Вот для этого они и придуманы, эти обобщённые типы, ёпта.
В чём прикол, блядь? Всё просто, как три копейки. Вместо того чтобы впиливать в класс конкретный тип вроде int, ты пишешь какую-нибудь букву — T, E, K, V. Это типа заглушка. А потом, когда создаёшь объект, говоришь: «Слушай, а вот тут вместо этой буквы T подставь-ка мне, пожалуйста, int». И всё, код становится универсальным, но при этом безопасным. Удивление пиздец, как элегантно.
Смотри, вот тебе коробка на все случаи жизни:
class Box<T> {
final T contents;
Box(this.contents);
T getItem() => contents;
}
void main() {
var intBox = Box<int>(42); // Тут T — это int, всё чётко
var stringBox = Box<String>('Hello'); // А тут T — уже String
// stringBox.getItem() + 5; // И вот тут компилятор тебе вмандюрит ошибку! Нельзя строку с числом мешать. Доверия ебать ноль к таким операциям.
}
Видишь? Создал коробку для чисел — клади туда только числа. Создал для строк — ну, извини, дружок, только строки. Попробуешь наебать систему — получишь по шапке на этапе компиляции. Красота.
А бывает, что нужно ограничить фантазию. Нельзя же позволять этому T быть чем угодно, а то вдруг он захочет быть, я не знаю, bool в математическом классе. Для этого есть extends.
// Этот контейнер работает ТОЛЬКО с числами (int, double). Всё остальное — на хуй.
class NumericContainer<T extends num> {
List<T> _values = [];
void add(T value) => _values.add(value);
T sum() => _values.fold(0 as T, (a, b) => (a + b) as T);
}
void main() {
var container = NumericContainer<int>();
container.add(10);
container.add(20);
print(container.sum()); // 30, всё гуд
// var badContainer = NumericContainer<String>(); // А вот это уже не прокатит. Компилятор скажет: «Чувак, ты чё, охренел? String не extends num!». И будет прав, сука.
}
Вот так, блядь, ставишь ограничение extends num и спишь спокойно. Никаких сюрпризов.
Где эта хрень валяется в Dart и Flutter? Да везде, ядрёна вошь! Смотри:
- Коллекции:
List<E>,Map<K, V>,Set<E>— это же всё дженерики, ебать копать. - Асинхронность:
Future<T>— обещает вернуть тебе что-то типаT,Stream<T>— стримит тебе объекты типаT. - Виджеты во Flutter:
ValueListenableBuilder<T>,FutureBuilder<T>— подстраиваются под твой тип данных. - State Management:
Provider<T>в том же Riverpod — вообще вся суть в этомT.
Короче, без дженериков — никуда. Это как универсальная отвёртка в мире типов. Выучил принцип — и потом везде его применяешь, волнение ебать от такой мощи.
Видео-ответы
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶