如何将可重用字段添加到Scala枚举?

时间:2014-04-28 20:19:59

标签: scala enums field reusability extending

我想用自定义字段扩展Scala的Enumeration实现,比如label。应该可以通过该枚举的values访问该新字段。此外,该自定义字段应该是Enumeration的各种实现的一部分。

我在Stackoverflow上发现了以下问题:

然而,他们都没有解决我的问题:

第一个问题是我可以添加自定义字段。但是,我无法通过Values返回的Enumeration.values访问该附加字段。以下代码可以工作并打印2nd enumeration value

object MyEnum extends Enumeration {
  type MyEnum = MyVal
  val VALUE_ONE = MyVal()
  val VALUE_TWO = MyVal(Some("2nd enumeration value"))
  val VALUE_THREE = MyVal(Some("3rd value"))

  case class MyVal(label: Option[String] = None) extends Val(nextId)
}
import MyEnum._

println(VALUE_TWO.label.get)

请注意,我通过其中一个值访问标签。以下代码不起作用:

for (value <- MyEnum.values) println(value.label)

错误消息如下:error: value label is not a member of MyEnum.Value

显然,使用MyEnum.MyVal代替MyEnum.Val。后者没有定义label,而我的自定义值会提供字段label

第二个问题是,似乎只能在Value的上下文中分别引入自定义ValEnumeration。因此,据我所知,不可能在不同的枚举中使用这样的字段。至少,以下代码无法编译:

case class MyVal(label: Option[String] = None) extends Enumeration.Val(nextId)

object MyEnum extends Enumeration {
  type MyEnum = MyVal
  val VALUE_ONE = MyVal()
  val VALUE_TWO = MyVal(Some("2nd enumeration value"))
}

object MySecondEnum extends Enumeration {
  type MySecondEnum = MyVal
  val VALUE_ONE = MyVal()
  val VALUE_TWO = MyVal(Some("2nd enumeration value"))
}

由于类Val受到保护,案例类MyVal无法访问Val - MyVal未在枚举的上下文中定义。

知道如何解决上述问题吗?

1 个答案:

答案 0 :(得分:2)

最近一个问题my answer to which got no love解决了第一个问题。

对于该用例,我会使用有用的类型编写自定义widgets方法,但我的链接答案(仅引入隐式转换)似乎非常方便。我不知道为什么它不是规范的解决方案。

对于第二个问题,您的派生MyVal应该只实现一个特征。

样品:

scala> trait Labelled { def label: Option[String] }
defined trait Labelled

scala> object A extends Enumeration { case class AA(label: Option[String]) extends Val with Labelled ; val X = AA(Some("one")) }
defined object A

scala> object B extends Enumeration { case class BB(label: Option[String]) extends Val with Labelled ; val Y = BB(None) }
defined object B

scala> val labels = List(A.X, B.Y)
labels: List[Enumeration#Val with Product with Labelled] = List(X, Y)

scala> labels map (_.label)
res0: List[Option[String]] = List(Some(one), None)