我有一个字符串格式化函数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}?!")
}
}
Run Code Online (Sandbox Code Playgroud)
IllegalArgumentException("??? 'myVal', scala.Enumeration.Val?!")当我传入scala枚举值时抛出一个.但是,添加一个
case a: scala.Enumeration.Val => "Hello enum"
Run Code Online (Sandbox Code Playgroud)
不编译:object枚举不是包scala的成员注意:class Enumeration存在,但它没有伴随对象.
如何检测传入的实例是否为scala枚举值?
if (a.getClass.getCanonicalName == "scala.Enumeration.Val") 应该工作,但感觉就像一个黑客 - 是否有任何实际类型模式匹配我可以做?
你犯了两个错误.首先,枚举的公共API的类的名称Value不是Val.其次,在提到内部类时,你使用#而不是..后者表示特定实例的内部类; 前者的意思是"对某些人来说Enumeration,我不关心哪一个,这是其内部类价值的一个实例").
所以,写这样:
case a: scala.Enumeration#Value => "Hello, enum!"
Run Code Online (Sandbox Code Playgroud)
如果你真的意味着你需要知道什么时候它是受保护的实现类Val而不是面向公众Value,你不能轻易地因为它受到保护.它应该是一个实现细节.但是你可以把你的比赛放在扩展Enumeration的东西里,然后你可以得到Val.(使用#符号.)