あなたは型の安全を捨てて、反射を使用することに頼らなければならないと思います。
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の質問にanswereする
EDIT
。
a)foo.doFooを呼び出す方法は? (つまり、オブジェクトはありません。doFooを定義するクラスのインスタンスです。)
val fooFunc
は、それがインスタンスapplyMeth.invoke(fooFunc, seq :_*)
の起動時に呼び出される関数を適用することであるFunction2
のインスタンスです。
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)
}
'ys'の要素数が3個未満の場合はどうなりますか? – huynhjl
関数 'f'のオーバーロードは頭に浮かぶものです。それはあなたが提供した方法で関数を呼び出すことができますが、他の状況では失敗するでしょう –