В чем разница между mixin и extension в Dart?

«В чем разница между mixin и extension в Dart?» — вопрос из категории Dart Core, который задают на 29% собеседований Flutter Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Mixin — это способ внедрения функциональности в несколько классов без использования наследования. Миксины могут содержать методы, геттеры, сеттеры и даже поля с состоянием. Они подключаются к классу с помощью ключевого слова with.

mixin ValidationMixin {
  String? _email;

  bool isValidEmail(String email) {
    return RegExp(r'^[^@]+@[^@]+.[^@]+').hasMatch(email);
  }

  void setEmail(String email) {
    if (isValidEmail(email)) _email = email;
  }
}

class User with ValidationMixin {
  void register(String email) {
    setEmail(email);
    print('Email set: $_email');
  }
}

Extension — позволяет добавлять новые методы к существующим типам, даже к типам из сторонних библиотек или встроенным типам Dart. Extensions не могут добавлять поля с состоянием и не изменяют оригинальный класс.

extension DateTimeExtension on DateTime {
  String toFormattedString() {
    return '${day.toString().padLeft(2, '0')}.${month.toString().padLeft(2, '0')}.$year';
  }
}

void main() {
  final now = DateTime.now();
  print(now.toFormattedString()); // Например: 15.04.2024
}

Ключевые различия:

  1. Назначение: Mixin для повторного использования кода с состоянием в иерархии классов, extension для добавления utility-методов к существующим типам.
  2. Состояние: Mixin может содержать поля (состояние), extension — нет.
  3. Использование: Mixin применяется с with при объявлении класса, extension методы доступны автоматически для экземпляров типа.
  4. Ограничения: Класс может использовать несколько mixins, но extension не может переопределять существующие методы типа.