覆盖 Scala 枚举值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2507273/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Overriding Scala Enumeration Value
提问by Ralph
As far as I can tell, Scala has definitions for the Enumeration Value class for Value(Int), Value(String), and Value(Int, String).
据我所知,Scala 为 Value(Int)、Value(String) 和 Value(Int, String) 定义了枚举值类。
Does anyone know of an example for creating a new Value subclass to support a different constructor?
有谁知道创建一个新的 Value 子类以支持不同的构造函数的示例?
For example, If I want to create an Enumeration with Value(Int, String, String) objects, how would I do it? I would like all of the other benefits of using the Enumeration class.
例如,如果我想用 Value(Int, String, String) 对象创建一个枚举,我该怎么做?我想要使用 Enumeration 类的所有其他好处。
Thanks.
谢谢。
回答by Thomas Jung
The Enumeration values are instance of the Val class. This class can be extended and a factory method can be added.
枚举值是 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
回答by Nikita Volkov
Actually in Scala Enumeration has a much simpler meaning than in Java. For your purpose you don't have to subclass Enumeration nor its Value in any way, you just need to instantiate your own type in its companion object as a val. This way you'll get the familiar access model of val value:MyEnum = MyEnum.Valueas you had in Java which is not possible in the example provided by Thomas Jung. There you'll have def value:My.MyVal = MyEnum.Valuewhich is kinda confusing as it seems to me besides all the hackiness of the solution. Here's an example of what I propose:
实际上,在 Scala 中枚举的含义比在 Java 中简单得多。出于您的目的,您不必以任何方式子类化 Enumeration 或其 Value,您只需要在其伴随对象中将您自己的类型实例化为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")
}
Here you'll find a more complicated example: Scala Best Practices: Trait Inheritance vs Enumeration
在这里你会发现一个更复杂的例子:Scala Best Practices: Trait Inheritance vs Enumeration
回答by James
Here is another simpler approach:
这是另一种更简单的方法:
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>
回答by apnith
I would prefer doing it by extending the Enumeration.Valclass.
我更愿意通过扩展Enumeration.Val课程来做到这一点。
For your requirement, I would post a sample below:
根据您的要求,我将在下面发布示例:
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]
}
Accessing values is as below:
访问值如下:
scala> FileType.csv
res0: FileType.Val = csv
scala> FileType.csv.delimiter
res29: String = ,

