Как работают extension-методы в Dart на уровне компиляции?

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

Ответ

Extension-методы в Dart — это синтаксический сахар, который компилятор преобразует в статические вызовы. Они не модифицируют исходный класс и не добавляют новых членов в его интерфейс во время выполнения (runtime).

Как это работает под капотом:

  1. Компилятор заменяет вызов метода расширения на вызов статической функции.
  2. Целевой объект передается в эту статическую функцию как явный параметр.
  3. Разрешение (resolution) нужного extension происходит во время компиляции на основе типа переменной и импортированных областей видимости.

Пример:

extension NumberParsing on String {
  int parseInt() {
    return int.parse(this);
  }
}

void main() {
  // Для компилятора этот вызов:
  print('42'.parseInt());
  // Фактически преобразуется в нечто подобное:
  print(NumberParsing('42').parseInt());
}

Ключевые ограничения и особенности:

  • Нет полей: Extensions не могут добавлять поля в класс, только методы, геттеры, сеттеры и операторы.
  • Нет переопределения: Если у класса уже есть метод с таким же именем, extension-метод игнорируется. Приоритет всегда у оригинального метода класса.
  • Статическая природа: Они не имеют доступа к приватным (_) членам расширяемого класса.
  • Работа с nullable: Синтаксис String?.parseInt() возможен благодаря специальным nullable-расширениям (с Dart 2.7+).