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

Какая у Dart типизация?

1.0 Junior🔥 171 комментариев
#Dart#ООП и паттерны

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

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

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

Типизация в Dart

Дарт имеет динамическую, постепенную, звуконепроницаемую типизацию (sound type system). Это означает, что типы могут быть как явно объявлены, так и выведены автоматически, но при этом гарантируется безопасность типов.

Основные характеристики

1. Звуконепроницаемая типизация (Sound Type System)

// ✅ Безопасный код — типы гарантированы
int add(int a, int b) {
  return a + b;
}

final result = add(5, 10); // result имеет тип int

// ❌ Ошибка при компиляции
final invalid = add(5, 'text'); // Error: The argument type 'String' can't be assigned to the parameter type 'int'

Дарт гарантирует, что если код проходит анализ типов, то не будет runtime ошибок типов.

2. Постепенная типизация (Gradual Typing)

// ❌ Старый стиль (позволяется, но плохо)
var data = getData(); // тип неизвестен
data.unknownMethod(); // может привести к ошибке рантайма

// ✅ Явная типизация (рекомендуется)
Map<String, dynamic> data = getData();
String name = data['name'] as String; // явное приведение

// ✅ Использование динамических типов
dynamic value = getData();
value.anyMethod(); // может быть опасно!

Вы можете писать код без типов (как в JavaScript), но чем больше явной типизации, тем безопаснее и быстрее код.

3. Ключевые особенности

Явная типизация

// Объявление переменной с типом
int age = 30;
String name = 'John';
List<String> items = ['apple', 'banana'];
Map<String, int> scores = {'Alice': 95, 'Bob': 87};

// Функция с типами
String greet(String name, int age) {
  return 'Hello, $name! You are $age years old.';
}

Вывод типов (Type Inference)

// Dart сам определит тип
var age = 30; // тип: int
var name = 'John'; // тип: String
var items = ['apple', 'banana']; // тип: List<String>

// Параметры функции могут быть выведены
final numbers = [1, 2, 3];
final doubled = numbers.map((n) => n * 2); // n автоматически int

Nullable типы (Null Safety)

// ❌ Строгий тип — не может быть null
String name = 'John';
name = null; // Error: The value 'null' can't be assigned to a variable of type 'String'

// ✅ Nullable тип — может быть null
String? nameOptional = 'John';
nameOptional = null; // Ok

// Использование
if (nameOptional != null) {
  print(nameOptional.length); // Ok, Dart знает что это не null
}

// Оператор ?.
int? length = nameOptional?.length; // null если nameOptional null

// Оператор ??
String name = nameOptional ?? 'Unknown'; // 'Unknown' если nameOptional null

Динамический тип (dynamic)

// ❌ dynamic — отключает проверку типов
dynamic data = 'text';
data = 123; // Ok
data.unknownMethod(); // Компилятор не проверит, ошибка возможна в рантайме

// ✅ Используйте Object или явные типы вместо dynamic
Object value = 'text';
if (value is String) {
  print(value.length); // Dart знает что это String
}

Обобщённые типы (Generics)

// Контейнер с типобезопасностью
List<String> names = ['Alice', 'Bob'];
Map<String, int> ages = {'Alice': 30, 'Bob': 25};

// Обобщённая функция
T first<T>(List<T> list) {
  return list.isEmpty ? throw Exception('Empty') : list.first;
}

String firstName = first<String>(['Alice', 'Bob']);
int firstNumber = first<int>([1, 2, 3]);

// Ограничения на типы (bounds)
class Repository<T extends Model> {
  void save(T item) {
    // T гарантированно имеет методы Model
  }
}

Типы Union (через sealed классы)

// Dart 3.0+ — pattern matching для типов
sealed class Result<T> {}

class Success<T> extends Result<T> {
  final T data;
  Success(this.data);
}

class Error<T> extends Result<T> {
  final String message;
  Error(this.message);
}

// Обработка
String handleResult<T>(Result<T> result) {
  return switch (result) {
    Success(data: var data) => 'Success: $data',
    Error(message: var msg) => 'Error: $msg',
  };
}

Type Casting и проверка типов

// Проверка типа
if (value is String) {
  print('It is String');
}

// Type casting (небезопасно)
final str = value as String; // Ошибка если не String

// Безопасное приведение
final str = value is String ? value : 'fallback';

// Pattern matching (Dart 3.0+)
switch (value) {
  case String s => print('String: $s'),
  case int i => print('Int: $i'),
  case _ => print('Other'),
}

Сравнение с другими языками

ЯзыкТипизацияNull SafetyПримечание
DartЗвуконепроницаемая + постепенная✅ (с Null Safety)Лучше всего
PythonДинамическаяType Hints опциональны
JavaScriptДинамическаяTypeScript добавляет типы
SwiftСтатическаяПохожа на Dart
JavaСтатическаяOptional для null

Flutter лучшие практики

1. Всегда явно типизируйте функции

// ❌ Плохо
getUser() {
  return {'name': 'John', 'age': 30};
}

// ✅ Хорошо
Map<String, dynamic> getUser() {
  return {'name': 'John', 'age': 30};
}

// ✅ Ещё лучше — используйте классы
class User {
  final String name;
  final int age;
  User({required this.name, required this.age});
}

User getUser() => User(name: 'John', age: 30);

2. Используйте const где возможно

// ✅ Const гарантирует неизменяемость типов
const String apiUrl = 'https://api.example.com';
const List<String> allowedRoles = ['admin', 'user'];

3. Обработка nullable типов

// ❌ Плохо
String getString() {
  return userData['name']; // может быть null!
}

// ✅ Хорошо
String? getString() {
  return userData['name'];
}

String displayName(String? name) {
  return name?.toUpperCase() ?? 'UNKNOWN';
}

Конкретные примеры в Flutter

// Widget с типизацией
class MyButton extends StatelessWidget {
  final String label;
  final VoidCallback onPressed;
  final Color? backgroundColor;
  
  const MyButton({
    required this.label,
    required this.onPressed,
    this.backgroundColor,
  });
  
  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      style: ElevatedButton.styleFrom(
        backgroundColor: backgroundColor,
      ),
      onPressed: onPressed,
      child: Text(label),
    );
  }
}

// Использование
MyButton(
  label: 'Click me',
  onPressed: () => print('Clicked'),
  backgroundColor: Colors.blue,
)

Вывод

Дарт имеет звуконепроницаемую типизацию с null safety, что делает его одним из самых безопасных языков для разработки мобильных приложений. Компилятор гарантирует отсутствие типо-безопасных ошибок при правильном использовании типов.