Start Debugging

Dot shorthands в Dart 3.12: убираем имя типа из кода Flutter

Dot shorthands стали стабильными в Dart 3.12.2. Пишите .center или .new и позвольте компилятору вывести тип из контекста. Вот как это работает с enum, статическими членами и конструкторами.

Если ваше дерево виджетов Flutter представляет собой стену из MainAxisAlignment.center, CrossAxisAlignment.start и EdgeInsets.all, Dart только что дал вам способ удалить значительную часть этих повторений. Dot shorthands, возможность писать .center и позволять компилятору определить тип, стали стабильными в Dart 3.12.2. Flutter 3.44 уже поставляется с Dart 3.12, так что если вы на текущем стабильном канале, вы можете использовать это уже сегодня.

Что на самом деле делает ведущая точка

Dot shorthand — это выражение, которое начинается с голой .. Когда окружающий контекст делает целевой тип однозначным, Dart разрешает член относительно этого типа, вместо того чтобы заставлять вас выписывать его полностью. Классический случай — enum в присваивании:

Status currentStatus = .running; // Instead of Status.running

Переменная объявлена как Status, поэтому .running может означать только Status.running. Тот же вывод срабатывает внутри switch, где сопоставляемое значение уже фиксирует тип:

return switch (level) {
  .debug => 'gray',
  .info => 'blue',
  .warning => 'orange',
  .error => 'red',
};

Это не только для enum

Механизм универсален: любой статический член, доступный через тип контекста, подходит. Сюда входят статические методы, статические геттеры, именованные конструкторы и фабричные конструкторы.

int port = .parse('8080');      // int.parse('8080')
BigInt zero = .zero;            // BigInt.zero
Point origin = .origin();       // Point.origin() named constructor
Point p = .fromList([1.0, 2.0]); // Point.fromList(...) factory

Безымянный конструктор получает для этой цели имя: .new. Именно эта деталь делает возможность окупающейся в реальном коде Flutter, где вы постоянно присваиваете только что сконструированные объекты типизированным полям:

final ScrollController _scrollController = .new();
final GlobalKey<ScaffoldMessengerState> scaffoldKey = .new();

Единственное правило, о которое спотыкаются

У равенства есть особый случай. Когда вы используете shorthand в правой части == или !=, Dart берёт статический тип левого операнда в качестве контекста:

if (myColor == .green) {
  print('The color is green.');
}

Здесь myColor имеет тип Color, поэтому .green разрешается в Color.green. Shorthand должен находиться в правой части. Переверните на .green == myColor — и не будет типа левого операнда, из которого можно вывести тип, так что это не скомпилируется.

Как это включить

Dot shorthands требуют версии языка не ниже 3.10, и возможность достигла стабильного состояния в Dart 3.12.2. Если вы уже на Flutter 3.44, она у вас есть. Поднимите ограничение SDK в pubspec.yaml до ^3.12.0, и анализатор перестанет помечать ведущую точку. Нет затрат во время выполнения и нет изменений в сгенерированном коде: это чистый синтаксис, который во время компиляции разрешается в полностью квалифицированный член, который вы бы всё равно написали.

Выигрыш — не в более коротком коде ради него самого. Дело в том, что тип появляется лишь один раз, в объявлении, а не повторяется у каждого значения. Полный набор правил разрешения см. на странице языка о dot shorthands.

Comments

Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.

< Назад