覆盖Scala枚举值

32
据我所知,Scala为枚举值类Value(Int)、Value(String)和Value(Int, String)提供了定义。
有没有人知道如何创建一个新的Value子类来支持不同的构造函数的示例?
例如,如果我想要创建一个带有Value(Int, String, String)对象的枚举,我该怎么做?我希望能够使用Enumeration类的所有其他优势。
谢谢。
4个回答

45

枚举值是Val类的实例。可以扩展此类并添加工厂方法。

object My extends Enumeration {
    val A = Value("name", "x")
    val B = Value("other", "y")
    class MyVal(name: String, val x : String) extends Val(nextId, name)
    protected final def Value(name: String, x : String): MyVal = new MyVal(name, x)
}

scala> My.B.id
res0: Int = 1

scala> My.B.x
res1: String = y

@Thomas Jung:您的想法很棒,但我无法使用它。出现了一个警告:“导入的`My'被包中对象的定义永久隐藏”。最后,我添加了这一行代码: type My = Value 到这个例子中,它就可以工作了。我仍然不明白为什么会这样,能否请您解释一下? - fahim ayat
要使用 My 枚举,您必须首先使用 import My._ 导入它,并在 My 对象中添加以下代码:type My = MyVal,这样您就可以访问 x 值。 - metch

1

实际上,在Scala中,枚举的含义比Java简单得多。对于您的目的,您不需要以任何方式子类化Enumeration或其Value,您只需要在其伴生对象中实例化自己的类型作为val。这样,您将获得与Java中相同的熟悉访问模型val value:MyEnum = MyEnum.Value,而这在Thomas Jung提供的示例中是不可能的。在那里,您将有def value:My.MyVal = MyEnum.Value,这有点令人困惑,因为除了解决方案的所有hackiness之外,它似乎对我来说。以下是我提出的一个示例:

class MyEnum(myParam:String)

object MyEnum {
  val Value1 = new MyEnum("any parameters you want")
  val Value2 = new MyEnum("")
  object Value3 extends MyEnum("A different approach to instantialization which also lets you extend the type in place")
}

在这里,您将找到一个更复杂的例子:Scala 最佳实践:特质继承 vs 枚举


1

我希望通过扩展Enumeration.Val类来完成它。

针对您的需求,我会在下面发布一个示例:

object FileType extends Enumeration {
  val csv = Val(1,"csv", ",")
  val tsv = Val(2,"tsv", "\t")
  protected case class Val(num: Int, fileType: String, delimiter: String) extends super.Val
  implicit def valueToFileType(x: Value): Val = x.asInstanceOf[Val]
}

访问值的方式如下所示:

scala> FileType.csv
res0: FileType.Val = csv

scala> FileType.csv.delimiter
res29: String = ,

0

这里有另一种更简单的方法:

scala> :paste
// Entering paste mode (ctrl-D to finish)

object Colors extends Enumeration {
  sealed case class Color private[Colors](hexCode: String, name: String) extends Val(name)

  val Black = Color("#000000", "black")
  val White = Color("#FFFFFF", "white")
}

// Exiting paste mode, now interpreting.

defined object Colors

scala> Colors.Black.hexCode
res0: String = #000000

scala> Colors.Black.name
res1: String = black

scala> Colors.values
res2: Colors.ValueSet = Colors.ValueSet(black, white)

scala> 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接