Scala Reflection:调用 Function1 的 apply 方法 - 多种选择?

Scala Reflection: Invoking a Function1's apply method - multiple alternatives?

我正在尝试使用 v2.11.6 中的 scala 反射 api 调用一个函数:

import scala.reflect.runtime.{universe => ru}

def f(i: Int) = i + 2

val fn: Any = (f _)
val ref = ru.runtimeMirror(ru.getClass.getClassLoader).reflect(fn)
val apply = ref.symbol.typeSignature.member(ru.TermName("apply"))

当使用 ref.reflectMethod(apply.asMethod) 时,它会抱怨 refapply 的多个替代方案。检查 apply.asTerm.alternatives 揭示了两种方法,一种带有签名 (x: Int)Int,另一种带有 (v1: T1)R。打电话

ref.reflectMethod(apply.asTerm.alternatives(1).asInstanceOf[ru.MethodSymbol])(1)

(与第二个选择)returns正确的结果(3)。然而,调用第一个替代方案会引发异常:java.lang.IllegalArgumentException: object is not an instance of declaring class

这些替代方案是什么?我如何确保始终调用正确的替代方案?使用此方法调用 Function2 或更高版本似乎也有问题,那么正确的方法是什么?

重载apply方法的原因是Function1@specialized原始类型。

我不知道是否有更好的方法来区分它们,但下面的方法似乎有效,寻找参数擦除为 AnyRef 的替代方法(而不是像 [=15 这样的原语=]):

def invoke(fun1: Any, arg1: Any): Any = {
  import scala.reflect.runtime.{universe => ru}
  val mirror  = ru.runtimeMirror(ru.getClass.getClassLoader)
  val ref     = mirror.reflect(fn)
  val applies = ref.symbol.typeSignature.member(ru.TermName("apply"))
  val syms    = apply.alternatives.map(_.asMethod)  
  val sym     = syms.find { m =>
    m.paramLists match {
      case (arg :: Nil) :: Nil 
        if arg.asTerm.typeSignature.erasure =:= ru.typeOf[AnyRef] => true
      case _ => false
    }
  } getOrElse sys.error("No generic apply method found")
  ref.reflectMethod(sym)(arg1)
}

// Test:
val fn: Any = (i: Int) => i + 2
invoke(fn, 1)  // res: 3