0

に引数を渡すよりも、その引数を出力するprint_args別のクロージャー、たとえば、を受け取るクロージャーを作成したいと思います。ff

これに対する私の最初の試みは次のとおりです。

def print_args(f) { { Object... args -> args.each { println it }; f(*args) } }

したがって、以下も定義するとします。

def add = { x, y -> x + y }

次に、次のことができます。

println add(1,2)

def print_args_add = print_args(add)

println print_args_add(1,2)

見てわかるように、print_args_addはただのクロージャーでありadd、引数を出力します。

を定義することもできますsum:

def sum = { x -> x.inject { acc, val -> acc + val } }

同様に:

println sum([1,2])

def print_args_sum = print_args(sum)
println print_args_sum([1,2])

これは、s を渡す場合にうまく機能しarrayListます。ただし、通常の配列を渡す場合:

Object x = new Object[2]
x[0] = 1
x[1] = 2

println sum(x)

正常に動作しますが、次のとおりです。

println print_args_sum(x)

クロージャーprint_argsが渡された配列をそのまま渡すのではなく展開するため、壊れます。

呼び出し元やクロージャーが処理できるものに追加の制約を課すことなく、単一の配列を引数として渡すことができるprint_argsクロージャーを処理できるように書く方法はありますか?fprint_args

コードを ideone hereに配置しました。

4

1 に答える 1

0

List渡された場合、オブジェクト配列を として扱います。

そのようにしなければならない理由は、sumパラメーターを 1 つしかとらないクロージャーのためです。オブジェクト配列のスプレッド演算子は、エラーが発生した場合に 2 つのパラメーターを生成します。したがって、以下の拡張が必要になりますprint_args

def print_args(f) { 
    {Object... args -> 
        args.each { println it}
        args.find{it instanceof List} ? f(*args) : f(args as List)
    }
}
于 2013-06-05T15:49:50.203 に答える