Scala 中的枚举具有多个构造函数参数

发布于 2024-08-13 04:31:21 字数 729 浏览 1 评论 0原文

我正在编写我的第一个大型 Scala 程序。在 Java 中,我有一个枚举,其中包含 UI 控件的标签和工具提示:

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 类仅采用一个 String 作为参数。我需要将其子类化吗?

谢谢。

I am writing my first large Scala program. In the Java equivalent, I have an enum that contains labels and tooltips for my UI controls:

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; }
}

Never mind the wisdom of using enums for this. There are other places that I want to do similar things.

How can I do this in Scala using scala.Enumeration? The Enumeration.Value class takes only one String as a parameter. Do I need to subclass it?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

ぶ宁プ宁ぶ 2024-08-20 04:31:21

您可以这样做,这与枚举的使用方式相匹配:

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!")

You could do this which matches how enums are used:

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!")
傻比既视感 2024-08-20 04:31:21

我想针对该问题提出以下解决方法:

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

唯一的一点不好的味道是通过 withName 获取枚举对象或apply 方法。你必须进行演员表转换:

val c: ControlText = ControlText.withName(name).asInstanceOf[ControlText]

I'd like to propose the following workaround for the issue:

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)
  }    
}

Now you can use ControlText as Java enum:

val c: ControlText
c.toolTipText

The only a little bad smell is to get enum object by withName or apply methods. You have to do a cast:

val c: ControlText = ControlText.withName(name).asInstanceOf[ControlText]
歌入人心 2024-08-20 04:31:21

根据 Mitch 的回答,如果您发现密封行为在将子类实例限制到定义基类的文件方面限制不够,您可以使用如下所示的对象(模块)定义:

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 关键字对于帮助检测模式匹配中的缺失情况仍然很重要。

Following on from Mitch's answer, if you find that the sealed behaviour is not restrictive enough in limiting subclassed instances to the file where the base class is defined, you can use an object (module) definition like this:

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!")
}

which obviously limits further instantiation of ControlText instances. The sealed keyword is still important in helping detect missing cases in pattern matching.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文