8

キーワードと演算子 (およびその他のもの) の列挙型があります。たとえば (すべて類似しています):

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この暗黙的な変換により、 s が期待される場所に列挙値を渡すことができます。

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
    ...
}

なんで?これを克服する方法は?

4

1 に答える 1

5

次の理由により、これは機能しません。

token match {
  case Keywords.ARRAY => println("Array")
  case _ => println("Something else")
}

基本的には、次の型シグネチャを持つPartialFunctionPartialFunction[Keywords.Value, Unit]です: . つまり、それはisDefinedAtであるか、その入力用ではないため、暗黙的は適用されません。

定義されていない場合はcase _ => ...、サンプル コードのすべてをキャッチします。まったく定義されておらず、一致するものがない場合は、MatchErrorがスローされます。

あなたのケースでは、タイプのみが定義されているため、一致がコンパイルされる部分関数でタイプが定義されていませtokenん。Token[Value]Keywords.Value

3つのソリューション

本当に暗黙が必要な場合は、明示的に暗黙を要求することができます (はい、その文は面白いです:))

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 {...}部分関数の本当の意味と意味を理解していただければ幸いです。

于 2013-11-12T00:20:27.987 に答える