Почему значение по умолчанию необязательного параметра должно быть постоянным? - PullRequest
2 голосов
/ 05 августа 2020
class Foo {
  final DateTime date;
  static final DateTime defDate = DateTime.now();
  
  Foo([this.date = defDate]); // Error
}

Что не так в этом коде, я предоставляю значение static final в качестве значения по умолчанию для необязательного параметра, но это неприемлемо для Dart, может ли кто-нибудь объяснить это поведение?

Изменить:

// Global field
final DateTime defDate = DateTime.now();

class A {
  void a([DateTime i = defDate]) => a; // Shouldn't have an error
}

class B extends A {
  @override
  void a([DateTime i = defDate]) => a; // Shouldn't have an error
}

1 Ответ

1 голос
/ 06 августа 2020

Значения по умолчанию Dart должны быть константой времени компиляции по ряду причин.

Прежде всего, значение по умолчанию считается частью сигнатуры методов экземпляра. Подклассы должны переопределять метод с параметрами, принимающими то же значение по умолчанию. Это бессмысленно, если значение неизвестно во время компиляции.

Более важно то, что нет ни одного очевидного момента, когда выражение должно быть вычислено. Dart намеренно избегает оценки чего-либо перед запуском main, чтобы уменьшить задержку запуска. Единственное исключение - константы времени компиляции, потому что они могут быть полностью вычислены во время компиляции. Это означает, что когда вы все используете функцию со значением по умолчанию в первый раз, значение по умолчанию еще не было оценено. В этот момент его определенно нужно будет оценить, по крайней мере, если вы опустите аргумент для параметра, поэтому компилятору, возможно, придется оценить произвольное выражение в середине вызова функции. Помимо дополнительных накладных расходов, что само по себе является проблемой, реальная проблема заключается в том, что они делают код непредсказуемым. В вашем примере значением по умолчанию будет DateTime.now(), которое было временем, когда функция была впервые вызвана.

Альтернативой будет оценка выражения значения по умолчанию каждый раз, когда функция вызывается без аргумента для этого параметра. Команда разработчиков языка Dart рассматривает этот вариант (как потенциальный будущий ход, без реальных текущих планов), но это будет означать отказ от идеи, что значение по умолчанию является частью подписи. Пока язык не делает этого, значение по умолчанию должно быть постоянным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...