确定 Any 实际上是一个 Scala 枚举值

Identify that an Any is actually a scala enumeration value

我有一个字符串格式化函数 fmt(v:Any): String,它需要根据 v 的运行时类型做不同的事情。所以它看起来像:

def fmt(v:Any): String = {
  v match {
    case a: Int => "Int: " + a
    case a: String => "\"" + a + "\""
    case a => throw new IllegalArgumentException(s"??? '$a', ${a.getClass.getCanonicalName}?!")
  }
}

当我传入 scala 枚举值时,这会抛出 IllegalArgumentException("??? 'myVal', scala.Enumeration.Val?!")。但是,添加

case a: scala.Enumeration.Val => "Hello enum"

不编译:object Enumeration 不是包 scala 的成员 注意:class枚举存在,但没有伴随对象。

如何检测传入的实例是scala枚举值?

if (a.getClass.getCanonicalName == "scala.Enumeration.Val") 应该可以,但感觉很糟糕 - 有没有我可以做的实际键入的模式匹配?

你犯了两个错误。首先,枚举的 public API 的 class 的名称是 Value 而不是 Val。其次,当引用内部 classes 时,您使用 # 而不是 .。后者表示特定实例的内部class;前者表示 "for some Enumeration, I don't care which, this is an instance of its inner class Value").

所以,这样写:

case a: scala.Enumeration#Value => "Hello, enum!"

如果你真的是说你需要知道什么时候它是受保护的实现 class Val 而不是面向 public 的 Value,你不能轻易因为,嗯,它受到保护。它应该是一个实现细节。但是你可以把你的匹配放在扩展 Enumeration 的东西里,然后你可以得到 Val。 (使用 # 表示法。)