【问题标题】:Scala: Inherited enum object doesn't satisfy parent traitScala:继承的枚举对象不满足父特征
【发布时间】:2021-04-20 17:25:30
【问题描述】:

我正在尝试在方法中使用 Enumeration 对象。枚举对象从特征扩展而来,该方法将特征作为参数。这是示例代码。

sealed trait canAdd
object DAdder extends Enumeration with canAdd
{
    type DAdder = Value
    val  P, Q = Value
}

class ClassTypeTest extends AnyFlatSpec with Matchers
{
    class AClass
    {
        def add(v: canAdd) = if(v.isInstanceOf[DAdder]) println("Got DAdder") else println("Got IAdder")
        def note(v: canAdd) = println("Got some canAdd trait object")
    }
    val aobj = new AClass
    val aseq: Seq[DAdder] = Seq(DAdder.P, DAdder.Q, DAdder.P)
    //*** Error in below line *****    
    aseq.foreach(aobj.add(_))
}

编译器给出以下错误:

Error:(23, 23) type mismatch;
 found   : x.x.DAdder.DAdder
    (which expands to)  x.x.DAdder.Value
 required: x.x.canAdd
    aseq.map(aobj.add(_))

我是否应该能够在将特征作为参数的方法中传递继承特征的对象?我该如何解决这个问题?

【问题讨论】:

  • DAdder 对象本身是 CanAdd,但枚举的元素不是。
  • 使用enumeratum 来实现您的意图,枚举是有限且不鼓励的。
  • @MateuszKubuszok 我检查了这个 - 看起来不错。你能把这个作为回应吗?我会接受。谢谢!

标签: scala types


【解决方案1】:

Enumeration 类不允许您扩展其值功能。基本上是:

abstract class Enumeratum {
  sealed trait Value { /* utilities */ }
  object Value { /* factory of Values */ }
 
  // utilities
}

由于您仅对 Enumeratum 类拥有控制权,因此您无法扩展 Values 这正是您所要求的。

您可以通过sealed traits 和case objects 轻松拥有此功能

sealed trait DAdder extends canadd
object DAdder {

  case object P extends DAdder
  case object Q extends DAdder
}

然而,这遗漏了一些实用程序,例如通过名称查找值、列出所有值等。

Enumeratum 库解决了这个问题,它要求您混合一些特征并粘贴一行 (val values = findValues) 以具有枚举的所有功能等等

import enumeratum._

sealed trait DAdder extends canadd
  with EnumEntry // mixin here
object DAdder extends Enum[DAdder] { // and mixin here

  case object P extends DAdder
  case object Q extends DAdder

  val values = findValues // and one line calling macro
}

(还有一些特殊的枚举应该存储一些原语/字符串作为它们在enumeratum.values._ 中的值)。

在 Scala 3 中,这可能看起来略有不同,因为它引入了 enum 关键字

sealed trait DAdder extends canadd
object DAdder {

  case object P extends DAdder
  case object Q extends DAdder
}

会变成

enum DAdder extends canadd {
  case P, Q
}

Scala 3 的枚举将定义ordinal 方法,因此像 Enumeratum 这样的库必须提供更少的功能。 (我想通过混合 Java 的 Enum 特征,您将可以访问values,所以其他一切都是扩展方法的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-14
    • 2020-11-11
    • 2015-06-08
    • 1970-01-01
    • 1970-01-01
    • 2010-10-19
    相关资源
    最近更新 更多