将类作为参数传递以检查局部变量

时间:2017-05-16 19:20:36

标签: scala class

我目前正在Scala中编写一个解析器,我正在尝试创建一个eat函数来检查下一个Token是否属于某个案例类,如果是,则使用它。我目前的尝试如下并正常工作:

def eat[T](tokenType: TypeTag[T]) = currentToken match {
  case Plus() => if (tokenType == typeTag[Plus]) currentToken = lexer.getNextToken() else throw new Exception(tokenType.toString ++ " expected, " ++ currentToken.toString)
  case Minus() => if (tokenType == typeTag[Minus]) currentToken = lexer.getNextToken() else throw new Exception(tokenType.toString ++ " expected, " ++ currentToken.toString)
}

Token定义如下:

trait Token
case class Plus() extends Token
case class Minus() extends Token
case class IntConst(n: Int) extends Token
case class FloatConst(x: Float) extends Token

之前我使用字符串来指定类型,但是传递TypeTag已经消除了尝试吃非现有类型的可能性。

然而, tldr,我想要实现的是能够传递一个类型或类作为参数,并检查currentToken是否属于该类。

我确实找到了如何将一个类作为参数传递给def something(c: class[_]),但后来我只知道如何将它与给定类型进行比较,比如Int。但是,我想将它与currentToken的类型进行比较。任何人都可以指出我朝着正确的方向努力实现这一目标吗?

感谢。

我希望实现的目标,(扩展版)

目前,我有工作代码,这是一种相对有效的方式(我认为)。但是,对于添加的每个Token个案类,即使eat函数回答的主要问题没有改变,也必须添加此函数的新行。在一个理想的世界里,我希望写出类似下面的伪代码:

def eat(tokenClass: Class) = {
    if (classOf(currentToken) == tokenClass) getNextToken else throw exception
}

永远不必延长。 (顺便说一下,如果参数只允许是特征令牌的案例类,那就更好了。)

1 个答案:

答案 0 :(得分:2)

由于你想要比较的是实际的运行时类(而不是编译时类型),你可以这样做:

def eat[T](implicit T: ClassTag[T]) =
  if (T.runtimeClass == currentToken.getClass) getNextToken else throw exception

但是,如果您的类具有类型参数(因为类型擦除),这将导致问题。