Overriding Scala Enumeration Value

*爱你&永不变心* 提交于 2019-12-17 15:39:19

问题


As far as I can tell, Scala has definitions for the Enumeration Value class for Value(Int), Value(String), and Value(Int, String).

Does anyone know of an example for creating a new Value subclass to support a different constructor?

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.

Thanks.


回答1:


The Enumeration values are instance of the Val class. This class can be extended and a factory method can be added.

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



回答2:


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.Value as you had in Java which is not possible in the example provided by Thomas Jung. There you'll have def value:My.MyVal = MyEnum.Value which is kinda confusing as it seems to me besides all the hackiness of the solution. Here's an example of what I propose:

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




回答3:


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> 



回答4:


I would prefer doing it by extending the Enumeration.Val class.

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 = ,


来源:https://stackoverflow.com/questions/2507273/overriding-scala-enumeration-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!