0

目前,我正在尝试Reader[Token]在 Scala 中解析 a 。因此,我想在解析步骤中检查 aToken是否是特定类的元素(例如AToken)。我可以使用以下代码轻松做到这一点:

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

这工作得很好。但我有几种类型要检查。所以对于每一种类型,我都需要在上面再写一遍。所以我想要一些acceptIfInstanceOf[T]自动(神奇地?)为 type 创建一个抽象方法T

我目前的解决方案仍然是两步:

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

然而,检查_.getClass == m.runtimeClass显然忽略了所有包含的子类型语义——仅仅是因为我们检查了两个对象_.isInstanceOf的相等性。Class

如果我想保持 的语义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] }

我从Stack Overflow 上的另一个问题中得到了上述解决方案。

于 2013-04-16T16:32:04.990 回答