我有关键字和运算符的枚举(以及其他一些),例如(都相似):
object Keywords extends Enumeration {
val AND, ARRAY, BEGIN, ...= Value
case class Keyword(keyword: Value) extends Token[Value] {
def this(keyword: String) = this(Keywords.fromString(keyword))
def value = keyword
}
implicit def valueToKeyword(keyword: Value) = new Keyword(keyword)
}
这种隐式转换允许我传递枚举值,其中Token
是预期的,例如
def testFunction[T](t: Token[T]) = ...
testFunction(Keywords.ARRAY) // gets converted
testFunction(Operators.PLUS) // gets converted too
似乎在匹配期间也没有应用相同的隐式转换,即
val token = new Keyword("ARRAY")
token match {
case Keywords.ARRAY => ... // not selected but SHOULD be
case Operators.PLUS => ... // completely different Enum
...
}
为什么呢?如何克服这个?
答案 0 :(得分:4)
这不起作用,因为:
token match {
case Keywords.ARRAY => println("Array")
case _ => println("Something else")
}
基本上是PartialFunction,具有以下类型签名:PartialFunction[Keywords.Value, Unit]
。这意味着隐含的胜利不会被应用,因为它要么是isDefinedAt,要么也不是该输入。
如果没有定义,case _ => ...
将会捕获我的示例代码中的所有内容。如果它没有完全定义且没有任何内容可以匹配,那么你将获得MatchError抛出。
在您的情况下token
类型Token[Value]
未在匹配将编译到的部分函数中定义,因为只定义了Keywords.Value
的类型。
如果你真的想要隐含,那么你可以明确地要求隐含(是的,那句话很有趣:))
implicitly[Keywords.Value](token) match {
case Keywords.ARRAY => println("Array")
case _ => println("Something else")
}
或者您可以明确说明token
的类型,以调用隐含的魔法:
val token: Keywords.Value = new Keyword("ARRAY")
token match {
case Keywords.ARRAY => println("Array")
case _ => println("Something else")
}
或者最简单的解决方案,如果你可以不受影响地生活:
token.value match {
case Keywords.ARRAY => println("Array")
case _ => println("Something else")
}
我知道这不是您正在寻找的答案,但我希望您了解match {...}
的真正含义和部分功能是什么。