【问题标题】:Groovy: Perfect forwardingGroovy:完美转发
【发布时间】:2013-06-05 03:19:49
【问题描述】:

我想做一个闭包,比如print_args,它需要另一个闭包,比如f,打印它的参数而不是将参数传递给f

我的第一次尝试如下:

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])

这适用于传递arrayLists。但是,在传递普通数组时:

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

println sum(x)

工作正常,但如下:

println print_args_sum(x)

中断,因为闭包 print_args 扩展了传递的数组,而不是按原样传递它。

有没有办法我可以编写print_args,这样它就可以处理闭包f,可以将单个数组作为参数传递,而不会对调用者施加额外的约束或闭包print_args 可以处理什么?

我已将代码放在 ideone here

【问题讨论】:

标签: groovy perfect-forwarding


【解决方案1】:

如果对象数组被传递,则将其视为List

您必须这样做的原因是因为sum 闭包只接受一个参数。对象数组上的扩展运算符在出错的情况下会产生两个参数。所以你需要在print_args中进行以下增强

def print_args(f) { 
    {Object... args -> 
        args.each { println it}
        args.find{it instanceof List} ? f(*args) : f(args as List)
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-07
    • 2020-09-12
    • 2017-08-05
    • 2015-04-11
    • 2017-07-17
    • 2022-01-22
    相关资源
    最近更新 更多