将一个类型为reflect.runtime.universe.MethodMirror的函数作为参数传递给方法

时间:2014-11-09 09:25:24

标签: scala reflection

我有一个类,其方法将函数作为参数。此功能是确定如何将文件拆分为块的策略。这是该方法的签名。

def split(r: RemoteFileInfo, append: Boolean, workDir: File, strategy: (Long) => Int = defaultStrategy): LinkedHashSet[Chunk] = {
  ...
}

有一个伴随对象提供了许多预定义的策略。我想通过将策略添加到配置文件来使策略可配置。这是配置文件中的一个片段。

downloader {
    ...
        dependencies {
            ...
            splitterStrategy = "ratioStrategy"
            ...
        }
 }

这是我的测试代码:

object Strategy {
    def ratioMinMaxStrategy(fileSize: Long): Int = fileSize.toInt
}

def splitTest(strategy: (Long) => Int): Unit = {
    println(s"strategy result=${strategy(100L)}")
}

splitTest(Strategy.ratioMinMaxStrategy)

这是我用来使用reflextion加载策略函数的代码:

val instanceMirror = ru.runtimeMirror(getClass.getClassLoader).reflect(Strategy)
val strategyMethod = ru.typeOf[Strategy.type].declaration(ru.newTermName("ratioMinMaxStrategy")).asMethod
val strategy = instanceMirror.reflectMethod(strategyMethod)
strategy(100L)
strategy(200L).asInstanceOf[Int]

代码单独工作,但当我合并它时,我得到一个错误'类型不匹配;发现:reflect.runtime.universe.MethodMirror required:Long => INT”。

splitTest(strategy)

我有什么建议可以解决这个问题吗?

问候,nidkil

1 个答案:

答案 0 :(得分:3)

正如类型不匹配错误消息所示,您已经提供了MethodMirror,其中包含(Any*) => Any类型的应用方法。此apply方法将其参数传递给您要通过反射调用的方法 - 在您的情况下是一个类型为Long => Int的函数。

由于编译器无法自动从(Any*) => Any转换为Long => Int,因此您必须手动执行此操作:

val strategyFunc: Long => Int = strategy(_).asInstanceOf[Int]
splitTest(strategyFunc)