← Назад к вопросам

Назови любимую фичу в Dart

2.0 Middle🔥 151 комментариев
#Dart

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Моя любимая фича в Dart

Если честно, у меня несколько любимых фич, но одна выделяется особенно — это Null Safety (nullable and non-nullable types) в сочетании с Pattern Matching. Позвольте объяснить почему и как это изменило мой код.

Primary фича: Null Safety

Это революционная фича, которая была введена в Dart 2.12. Null Safety радикально улучшает качество кода, предотвращая целый класс ошибок на этапе компиляции.

Суть проблемы

В старом Dart (и других языках как JavaScript, Java) null-ошибки были частой причиной crashes:

// Старый Dart (без Null Safety)
String name; // Может быть null
name.toUpperCase(); // Может вызвать runtime ошибку!

Решение: Null Safety

// Современный Dart
String name = 'John'; // Не может быть null
name.toUpperCase(); // 100% безопасно!

String? maybeNull = null; // Явно может быть null
if (maybeNull != null) {
  maybeNull.toUpperCase(); // Компилятор знает, что здесь не null
}

Почему это моя любимая фича

1. Ловит ошибки до runtime

class User {
  final String name;
  final String? email; // Явно может быть null
  
  void printEmail() {
    // Этот код не скомпилируется без проверки null
    // print(email.toLowerCase()); // Ошибка компиляции!
    
    // Вынуждены проверить
    if (email != null) {
      print(email.toLowerCase()); // OK
    }
  }
}

Это спасает часы отладки и предотвращает крахи в production.

2. Делает код более явным

// Сразу видно, какие значения могут быть null
class Article {
  final String title; // Всегда есть
  final String? summary; // Может быть null
  final List<String>? tags; // Может быть null
  final int? viewCount; // Может быть null
}

Это самодокументирующийся код.

3. Меньше проверок и более чистый код

// Без Null Safety требовалось много проверок
if (user != null && user.email != null && user.email.isNotEmpty) {
  sendEmail(user.email);
}

// С Null Safety и pattern matching
if (user case User(email: String email) when email.isNotEmpty) {
  sendEmail(email);
}

Вторая любимая фича: Pattern Matching (Dart 3.0+)

Pattern Matching в Dart стал невероятно мощным инструментом. Это больше, чем простой switch statement.

Примеры Pattern Matching

var number = 5;

switch (number) {
  case 0:
    print('Zero');
  case < 0:
    print('Negative');
  case > 0:
    print('Positive');
  case == 5:
    print('Exactly five');
}

Деструктуризация объектов

class Point {
  final int x;
  final int y;
  Point(this.x, this.y);
}

var point = Point(3, 4);

var distance = switch (point) {
  Point(x: 0, y: 0) => 'Origin',
  Point(x: var x, y: var y) when x == y => 'On diagonal',
  Point(x: var x, y: var y) => 'Distance: ${(x*x + y*y).sqrt()}',
};

Работа с sealed классами

sealed class Result<T> {}
final class Success<T> extends Result<T> {
  final T data;
  Success(this.data);
}
final class Error extends Result<Never> {
  final String message;
  Error(this.message);
}
final class Loading extends Result<Never> {}

var result = Success<String>('Hello');

var message = switch (result) {
  Success(:final data) => 'Got: $data',
  Error(:final message) => 'Error: $message',
  Loading() => 'Still loading...',
};

Guard clauses

var age = 15;

var status = switch (age) {
  < 0 => 'Invalid',
  < 13 => 'Child',
  < 18 when age >= 16 => 'Can drive in some places',
  < 18 => 'Teenager',
  >= 18 => 'Adult',
};

Как эти фичи работают вместе

// Реальный пример: обработка ответа от API
sealed class ApiResponse<T> {}
final class ApiSuccess<T> extends ApiResponse<T> {
  final T data;
  ApiSuccess(this.data);
}
final class ApiError extends ApiResponse<Never> {
  final String code;
  final String message;
  ApiError(this.code, this.message);
}
final class ApiLoading extends ApiResponse<Never> {}

// В UI
var response = await api.fetchUser('123');

var widget = switch (response) {
  ApiSuccess(data: User(name: var name, email: String? email)) => 
    UserCard(name: name, email: email),
    
  ApiError(code: '404', message: var msg) =>
    ErrorWidget('Not found: $msg'),
    
  ApiError(:final message) =>
    ErrorWidget('Error: $message'),
    
  ApiLoading() =>
    LoadingWidget(),
};

Другие люимые фичи (но менее importantes)

Spread operator

var list1 = [1, 2, 3];
var list2 = [4, 5, 6];
var combined = [...list1, ...list2]; // [1, 2, 3, 4, 5, 6]

var conditionalList = [1, 2, if (someCondition) 3];

Extension методы

extension StringUtils on String {
  String capitalize() {
    return this[0].toUpperCase() + this.substring(1);
  }
}

var text = 'hello';
print(text.capitalize()); // Hello

Cascade operator

var person = Person()
  ..name = 'John'
  ..age = 30
  ..email = 'john@example.com';
  
// Вместо
var person = Person();
person.name = 'John';
person.age = 30;
person.email = 'john@example.com';

Type inference

var list = [1, 2, 3]; // Dart автоматически знает, что это List<int>
var map = {'name': 'John', 'age': 30}; // Map<String, dynamic>

// Не нужно писать явные типы везде

Почему я люблю именно Null Safety + Pattern Matching

Безопасность:

  • Ошибки null-pointer ловятся до runtime
  • Компилятор помогает писать правильный код

Читаемость:

  • Pattern matching делает код очень выразительным
  • Меньше вложенных if-else
  • Структура кода более понятна

Производительность:

  • Меньше null-проверок в runtime
  • Компилятор может оптимизировать лучше

Удовлетворение:

  • Когда код компилируется, он работает
  • Меньше неожиданных ошибок
  • Чувствуешь доверие к своему коду

Пример до и после

Без Pattern Matching (Dart 1.0 стиль)

ApiResponse response = await api.fetch();

if (response is Success) {
  var successResponse = response as Success;
  var data = successResponse.data;
  if (data != null) {
    showData(data);
  } else {
    showError('No data');
  }
} else if (response is Error) {
  var errorResponse = response as Error;
  showError(errorResponse.message);
} else if (response is Loading) {
  showLoading();
}

С Pattern Matching (Dart 3.0+)

var response = await api.fetch();

switch (response) {
  Success(data: var data) => showData(data),
  Error(:final message) => showError(message),
  Loading() => showLoading(),
}

Второй вариант безопаснее, короче и понятнее.

Итог

Моя любимая фича в Dart — это Null Safety, потому что она радикально улучшает безопасность кода. А Pattern Matching идеально дополняет это, делая код более выразительным и безопасным.

Эти две фичи вместе делают Dart одним из самых удобных языков для разработки, где ошибки ловятся рано, а код остаётся чистым и понятным.

Назови любимую фичу в Dart | PrepBro