0

Reader[Token]現在、 Scala でa を解析しようとしています。Tokenしたがって、解析ステップ中に a が特定のクラスの要素であるかどうかを確認したいと思います(例: AToken)。次のコードで簡単に実行できます。

def aToken = acceptIf(_.isInstanceOf[AToken])("Token " + _ + " is not of type AToken")
  ^^ { _.asInstanceOf[AToken] }  

これは完全に正常に機能します。しかし、私はチェックするいくつかのタイプがあります。したがって、すべてのタイプについて、その全体をもう一度上に書く必要があります。だから私はacceptIfInstanceOf[T]自動的に(魔法のように?) type の抽象メソッドを作成したいと思いTます。

私の現在の解決策はまだ2段階のものです:

def acceptIfInstanceOf[T](implicit m: Manifest[T]) : Parser[Elem] =
  acceptIf(_.getClass == m.runtimeClass)("" + _ + " is not of type " + m)
def aToken = acceptIfInstanceOf[AToken] ^^ { _.asInstanceOf[AToken] }

aTokenこれも機能しますが、関数アプリケーションを削除して に直接含めたいと思いますacceptIfInstanceOf。悲しいことに、これはうまくいきません:

def acceptIfInstanceOf[T](implicit m: Manifest[T]) : Parser[T] =
  acceptIf(_.getClass == m.runtimeClass)("" + _ + " is not of type " + m)
  ^^ { m.runtimeClass.cast(_) }

Scala コンパイラから次のエラー メッセージが表示されます。

scala: type mismatch;
found   : _$1 where type _$1
required: T
def acceptIfInstanceOf[T](implicit m: Manifest[T]): Parser[T] =
  acceptIf(_.getClass == m.runtimeClass)("" + _ + " is not of type " + m)
  ^^ { m.runtimeClass.cast(_) }
                          ^

そのようなものを構築することが可能かどうか、またその方法を誰かが知っていますか? ありがとう!

4

1 に答える 1

1

huynhjlが述べたよう_.asInstaceOf[T]に代わりに使用すると、最初の問題が解決されます。m.runtimeClass.cast(_)

def acceptIfInstanceOf[T](implicit m: Manifest[T]) : Parser[T] =
  acceptIf(_.getClass == m.runtimeClass)("" + _ + " is not of type " + m)
  ^^ { _.asInstanceOf[T] }

ただし、 2 つのオブジェクトの等価性をチェックするという理由だけで、このチェックでは、含まれ_.getClass == m.runtimeClassているすべてのサブタイプ セマンティクスが明らかに無視されます。_.isInstanceOfClass

のセマンティクスを維持したい場合はisInstanceOf、次のテストを使用する必要があります。

reflect.ClassManifest.singleType(_) <:< m

しかし、これは 2.10 で非推奨になったため、次のものに置き換えManifestTypeTag使用しています。

def acceptIfInstanceOf[T](implicit tag: TypeTag[T]): Parser[T] =
  acceptIf(currentMirror.reflect(_).symbol.toType <:< typeOf[T])
  ("" + _ + " is not of type " + tag.tpe)
  ^^ { _.asInstanceOf[T] }

上記の解決策は、スタック オーバーフローに関する別の質問から得ました。

于 2013-04-16T16:32:04.990 に答える