Как определить поля в перечисляющем классе built_value?

#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 .