反射错误地匹配按名称参数

时间:2016-08-01 18:49:26

标签: scala reflection

我正在尝试在方法定义中检测名称参数。我的方法基于this question's ByNameParam解决方案。

不幸的是,对于重复的参数,名称参数与TypeRef匹配,反之亦然。有关示例,请参阅以下代码。

我认为这不是预期的行为。是我的错误还是Definitions模块有问题?

import scala.reflect.runtime.universe._

class X { def x(i: => Int, other: Int*) = i * 2 }

val typeSignature = typeOf[X].member(TermName("x")).typeSignature
val paramTypes = typeSignature match {
  case MethodType(params, _) => params map { _.typeSignature }
}
val repeatedParamDefinition = definitions.RepeatedParamClass
val byNameDefinition = definitions.ByNameParamClass

// prints "Got repeatedParamDefinition" twice
paramTypes map { signature =>
  signature match {
    case TypeRef(_, repeatedParamDefinition, args) =>
      println("Got repeatedParamDefinition")
      args
    case TypeRef(_, byNameDefinition, args) => 
      println("Got byNameDefinition")
      args
  }
}

// Prints "Got byNameDefinition" twice
paramTypes map { signature =>
  signature match {
    case TypeRef(_, byNameDefinition, args) => 
      println("Got byNameDefinition")
      args
    case TypeRef(_, repeatedParamDefinition, args) =>
      println("Got repeatedParamDefinition")
      args
  }
}

Scala版本:2.11.4(OpenJDK 64位服务器VM,Java 1.8.0_65)

1 个答案:

答案 0 :(得分:1)

当您使用TypeRef(_, byNameDefinition, args)这样的模式时,byNameDefinition是一个新变量,而不是与现有val byNameDefinition的比较。由于该变量未被使用,因此它与TypeRef(_, _, args)实际上相同。要避免这种情况,您需要用反引号将其包围起来,或者以大写字母开头命名。