【问题标题】:How to add reusable field to Scala Enumeration?如何将可重用字段添加到 Scala 枚举?
【发布时间】:2014-04-28 20:19:58
【问题描述】:

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

我在 Stackoverflow 知道以下问题:

但是,它们都没有解决我的问题:

第一个问题是我可以添加自定义字段。但是,我无法通过Enumeration.values 返回的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.Val 代替MyEnum.MyVal。后者没有定义label,而我的自定义值将提供字段label

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

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 类受到保护,case 类MyVal 无法访问Val -- MyVal 未在枚举上下文中定义。

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

【问题讨论】:

    标签: scala enums field reusability extending


    【解决方案1】:

    最近的一个问题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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多