#dart #code-generation #built-value
#dart #генерация кода #встроенное значение
Вопрос:
Я хотел иметь EnumClass
необязательное message
поле, что-то вроде этого:
class Status extends EnumClass {
static const Status error = _$error;
static const Status completed = _$completed;
String message;
const Status._(String name) : super(name);
static BuiltSet<Status> get values => _$values;
static Status valueOf(String name) => _$valueOf(name);
}
Проблема в том, что я получаю это сообщение об ошибке:
Не удается определить конструктор const для класса с неокончательными полями.
И если я объявлю message
как final
, то я не смогу его инициализировать, поскольку конструктор скрыт.
Есть ли способ добиться этого? Может быть, создать сгенерированный конструктор перечислений?
Ответ №1:
Целью «перечисляемого типа» является создание предопределенного набора значений. Если бы вы разрешили клиентам создавать новые экземпляры Status, даже const , это свойство больше не сохранялось бы; valueOf()
метод выдавал бы исключение при передаче такого экземпляра и values
не содержал бы его. Таким образом, это нарушает контракт «перечисляемого типа».
// BAD: no longer an "enum type" if clients can create new instances
const Status.withMessage(String name, String message)
: message = message, super(name);
С другой стороны, если сообщение является постоянным для каждого перечисляемого значения и не предназначено для предоставления клиентами, вы можете просто добавить средство получения в класс:
// GOOD: Adding new methods, getters, or const-initialized member variables is fine.
String get message =>
_messages[this] ??
(throw StateError('No message for Status.$name'));
static const _messages = const {
error: "An error occurred.",
completed: "Successfully completed."
};
Комментарии:
1. Ну, значит, перечисляющий класс built_value не является перечислением Java, как многие говорят.
2. Java также не позволяет создавать новые экземпляры; только для того, чтобы связать постоянную информацию с существующими экземплярами во время определения. Это правда, что, похоже, в built_value нет точного эквивалента; ближайшим эквивалентом было бы определить средство получения, которое индексирует в private map, как в моем втором примере.
3. Если я правильно помню, в Java мы можем передавать переменные во время создания перечисления и получать их значения обратно, но прошло некоторое время, я это делал, и сейчас мне немного лениво искать в документах, хахаха в любом случае, что я сделал в итоге, это создал обычный Dart
enum
и передал его вbulit_value
класс типа значения, который содержитenum
и необязательныйmessage
.