Ответ
Из новшеств Dart 3 я чаще всего применяю Records и Pattern Matching, так как они делают код значительно чище.
1. Records (Записи)
Идеальны для возврата нескольких значений из функции без создания лишних классов или использования пакетов вроде tuple.
// Возврат нескольких значений из функции
(String, int, bool) getUserInfo() {
return ('Alice', 30, true);
}
void main() {
var userInfo = getUserInfo();
print(userInfo.$1); // Alice (позиционный доступ)
// Деструктуризация (pattern matching в объявлении)
var (name, age, isActive) = getUserInfo();
print('$name is $age years old.');
// Именованные записи — ещё удобнее
({String name, int score}) getScore() => (name: 'Bob', score: 95);
var scoreData = getScore();
print(scoreData.name); // Bob (именованный доступ)
}
2. Pattern Matching
Крайне полезен в switch и if для декомпозиции данных и exhaustive checking.
// Обработка разных состояний виджета или данных
sealed class ApiResult {}
class Success implements ApiResult {
final String data;
Success(this.data);
}
class Failure implements ApiResult {
final String error;
Failure(this.error);
}
void handleResult(ApiResult result) {
switch (result) {
// Декомпозиция объекта прямо в case
case Success(:final data):
print('Success with data: $data');
case Failure(:final error):
print('Error: $error');
// Компилятор проверит, что все варианты sealed-класса обработаны
}
}
// Использование в if-условиях
if (userInfo case (String name, int age) when age > 18) {
print('Adult user: $name');
}
3. Class Modifiers Использую для более строгого контроля дизайна библиотек.
final class: Чтобы запретить наследование от критически важного класса, например, от состояния BLoC.sealed class: Как в примере выше, для создания закрытых иерархий, которые идеально работают с pattern matching.
4. Обязательный Null Safety Все новые и поддерживаемые проекты теперь строго используют null safety, что исключает целый класс ошибок на этапе разработки.
Эти фичи не просто синтаксический сахар — они позволяют писать более выразительный, безопасный и легко рефакторимый код.
Ответ 18+ 🔞
А, ну это про Dart 3, да? Ёпта, вот реально, там такие штуки добавили, что иногда сам от себя охуеваешь, насколько код чище становится. Не то что раньше, блядь, костыли городить приходилось.
Ну смотри, из всего этого добра я чаще всего юзаю Records и Pattern Matching. Это просто пиздец как удобно, честно.
1. Records (или, по-нашему, записи) Раньше, если надо было из функции несколько значений вернуть — это ж был ёперный театр! Либо класс отдельный плоди, который только в одном месте используется, либо эти тупые кортежи из пакетов тащи. Теперь — красота.
// Возвращаешь кучу всего сразу, и не парься
(String, int, bool) getUserInfo() {
return ('Alice', 30, true);
}
void main() {
var userInfo = getUserInfo();
print(userInfo.$1); // Alice (доступ по позиции, старый способ)
// А вот это уже магия — деструктуризация нахуй!
var (name, age, isActive) = getUserInfo();
print('$name is $age years old.'); // Чисто, понятно, никакого геморроя
// А если с именами — вообще песня
({String name, int score}) getScore() => (name: 'Bob', score: 95);
var scoreData = getScore();
print(scoreData.name); // Bob — обращаешься по имени, а не по цифрам
}
Вот честно, после этого возвращаться к старому — как будто на дворе 2002-й год, блядь.
**2. Pattern Matching (Сопоставление с образцом)**
Вот это, блядь, сила. Особенно в `switch` заходит на ура. Раньше `switch` был такой, ну, так себе, для примитивов. А теперь на нём целые состояния приложения разбирать можно, да ещё и с гарантией, что ничего не упустил.
```dart
// Допустим, есть у нас sealed-классы для результата API
sealed class ApiResult {}
class Success implements ApiResult {
final String data;
Success(this.data);
}
class Failure implements ApiResult {
final String error;
Failure(this.error);
}
void handleResult(ApiResult result) {
switch (result) {
// Смотри, как красиво: сразу распаковываешь объект прямо в кейсе
case Success(:final data):
print('Success with data: $data');
case Failure(:final error):
print('Error: $error');
// И компилятор, сука, сам проверит, что ты все варианты sealed-класса обработал!
// Никаких забытых случаев, доверия — ебать ноль, но в хорошем смысле.
}
}
// И в ифах тоже работает, что вообще огонь
if (userInfo case (String name, int age) when age > 18) {
print('Adult user: $name'); // Только для взрослых, ящетаю
}
3. Модификаторы классов (Class Modifiers) Тоже полезная хуйня, особенно когда пишешь библиотеку и не хочешь, чтобы её ломали криворукие пользователи.
final class: Херачь на класс, который не должен иметь наследников. Идеально для какого-нибудь критичного стейта из BLoC, чтобы никто не накосячил.sealed class: Как раз для тех самых иерархий, которые потом вswitchидеально ложатся. Закрытый набор вариантов — и никаких неожиданностей.
4. Обязательный Null Safety
Ну это, блядь, святое. Все новые проекты теперь только с ним. Целый пласт ошибок, связанных с null, просто отваливается нахуй ещё на этапе написания кода. Волнение — ебать, но уже не нужно.
Короче, это не просто синтаксический сахар, как некоторые говорят. Это реальные инструменты, которые делают код выразительнее, безопаснее и проще для рефакторинга. Попробуешь — обратно не захочешь, честное пионерское.