Перечисления в Scala с несколькими параметрами конструктора - PullRequest
5 голосов
/ 02 декабря 2009

Я пишу свою первую большую программу Scala. В эквиваленте Java у меня есть перечисление, которое содержит метки и всплывающие подсказки для элементов управления пользовательского интерфейса:

public enum ControlText {
  CANCEL_BUTTON("Cancel", "Cancel the changes and dismiss the dialog"),
  OK_BUTTON("OK", "Save the changes and dismiss the dialog"),
  // ...
  ;

  private final String controlText;
  private final String toolTipText;

  ControlText(String controlText, String toolTipText) {
    this.controlText = controlText;
    this.toolTipText = toolTipText;
  }

  public String getControlText() { return controlText; }
  public String getToolTipText() { return toolTipText; }
}

Не берите в голову мудрость использования перечислений для этого. Есть и другие места, где я хочу делать подобные вещи.

Как я могу сделать это в Scala, используя scala.Enumeration? Класс Enumeration.Value принимает только одну строку в качестве параметра. Нужно ли подкласс его?

Спасибо.

Ответы [ 3 ]

15 голосов
/ 02 декабря 2009

Вы можете сделать это в соответствии с тем, как используются перечисления:

sealed abstract class ControlTextBase
case class ControlText(controlText: String, toolTipText: String)
object OkButton extends ControlText("OK", "Save changes and dismiss")
object CancelButton extends ControlText("Cancel", "Bail!")
8 голосов
/ 10 июля 2013

Я хотел бы предложить следующий способ решения проблемы:

object ControlText extends Enumeration {

  type ControlText = ControlTextValue

  case class ControlTextValue(controlText: String, toolTipText: String) extends Val(controlText)

  val CANCEL_BUTTON = ControlTextInternalValue("Cancel", "Cancel the changes and dismiss the dialog")
  val OK_BUTTON = ControlTextInternalValue("OK", "Save the changes and dismiss the dialog")

  protected final def ControlTextInternalValue(controlText: String, toolTipText: String): ControlTextValue = {
    ControlTextValue(controlText, toolTipText)
  }    
}

Теперь вы можете использовать ControlText в качестве перечисления Java:

val c: ControlText
c.toolTipText

Единственный неприятный запах - получить объект enum withName или apply методами Вы должны выполнить приведение:

val c: ControlText = ControlText.withName(name).asInstanceOf[ControlText]
1 голос
/ 05 декабря 2009

Исходя из ответа Митча, если вы обнаружите, что запечатанное поведение недостаточно ограничивает ограничение подклассовых экземпляров файлом, в котором определен базовый класс, вы можете использовать определение объекта (модуля), например:

object ControlTexts {
  sealed abstract class ControlTextBase

  case class ControlText private[ControlTexts] (controlText: String, 
                                                toolTipText: String)
          extends ControlTextBase

  object OkButton     extends ControlText("OK", "Save changes and dismiss")
  object CancelButton extends ControlText("Cancel", "Bail!")
}

, что явно ограничивает дальнейшее создание экземпляров экземпляров ControlText. Ключевое слово sealed по-прежнему важно для выявления пропущенных случаев при сопоставлении с образцом.

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