【发布时间】:2010-03-24 11:41:44
【问题描述】:
据我所知,Scala 为 Value(Int)、Value(String) 和 Value(Int, String) 定义了枚举值类。
有谁知道创建新 Value 子类以支持不同构造函数的示例?
例如,如果我想用 Value(Int, String, String) 对象创建一个枚举,我该怎么做?我想要使用 Enumeration 类的所有其他好处。
谢谢。
【问题讨论】:
标签: scala enumeration
据我所知,Scala 为 Value(Int)、Value(String) 和 Value(Int, String) 定义了枚举值类。
有谁知道创建新 Value 子类以支持不同构造函数的示例?
例如,如果我想用 Value(Int, String, String) 对象创建一个枚举,我该怎么做?我想要使用 Enumeration 类的所有其他好处。
谢谢。
【问题讨论】:
标签: scala enumeration
枚举值是 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
【讨论】:
My枚举,你必须先用import My._导入它,并在My对象中添加以下代码:`type My = MyVal`,这样你就可以访问x 值。
实际上,在 Scala 中枚举的含义比在 Java 中简单得多。出于您的目的,您不必以任何方式继承 Enumeration 或其值,您只需在其伴随对象中将您自己的类型实例化为val。这样,您将获得熟悉的val value:MyEnum = MyEnum.Value 访问模型,就像在 Java 中所拥有的那样,这在 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 Best Practices: Trait Inheritance vs Enumeration
【讨论】:
这是另一种更简单的方法:
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>
【讨论】:
我更喜欢通过扩展 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 = ,
【讨论】: