我认为您将不得不抛弃类型安全并诉诸使用反射。
scala> object Foo {
| def doFoo(i:Int, s:String) = println(s * i)
| }
defined module Foo
scala> val fooFunc = Foo.doFoo _
fooFunc: (Int, String) => Unit = <function2>
scala> val applyMeth = fooFunc.getClass.getMethods()(0)
applyMeth: java.lang.reflect.Method = public final void $anonfun$1.apply(int,java.lang.String)
scala> val i:Integer = 5
i: Integer = 5
scala> val seq = Seq[Object](i,"do the foo! ")
seq: Seq[Object] = List(5, "do the foo! ")
scala> applyMeth.invoke(fooFunc, seq :_*)
do the foo! do the foo! do the foo! do the foo! do the foo!
res59: Object = null
但是,除非您正在创建一些 DSL 并且确实需要这种功能,否则我会尝试寻找另一种方法。如果方法在您的控制之下,则重载方法,或者将其包装在某种外观类中。
编辑
在评论中回答 Rubistro 的问题。
a) 这种技术如何调用 foo.doFoo?(也就是说,你没有对象——只有一个定义 doFoo 的类的实例。)
val fooFunc
是 a 的一个实例,Function2
它是在调用 时调用的实例应用函数applyMeth.invoke(fooFunc, seq :_*)
。
b) 此方法是否允许在 seq 中的值之前和之后将参数传递给 doFoo?
不是直接的。要使用它,您必须在调用该方法之前构建您的序列。但是,由于它是一个序列,因此您可以在调用该方法之前轻松地将值添加/附加到您正在使用的序列中。将其包装在构建器中可能很有用,例如
class InvokationBuilder(meth:java.lang.reflect.Method, args: List[Object] = Nil) {
def invoke(instance:Object) = meth.invoke(instance, args.toSeq :_*)
def append(arg:Object) = new InvokationBuilder(meth, args :+ arg)
def prepend(arg:Object)= new InvokationBuilder(meth, arg :: args)
}