文章目录
一、闭包参数绑定
1、闭包参数绑定 curry 函数
2、闭包参数绑定 rcurry 函数
3、闭包参数绑定 ncurry 函数
二、完整代码示例
一、闭包参数绑定
闭包 Closure 提供了 curry , ncurry , rcurry 方法 , 这 3 33 个方法可以将 闭包 进行 参数绑定 ;
curry 函数 : 从左到右 绑定 闭包参数 ;
rcurry 函数 : 从右到左 绑定 闭包参数 ;
ncurry 函数 : 指定从第 n nn 个参数开始绑定 闭包参数 ;
上述 3 33 个方法都会 创建一个新的闭包 , 需要使用 新的变量接收新创建的闭包 , 原来的闭包变量保持不变 ;
1、闭包参数绑定 curry 函数
从左到右绑定参数 ;
闭包参数绑定 curry 函数原型 :
/** * 从左到右进行参数绑定 * <p> * 典型用法: * <pre class="groovyTestCase"> * def multiply = { a, b {@code ->} a * b } * def doubler = multiply.curry(2) * assert doubler(4) == 8 * </pre> * 注:对闭包 vararg 类型的功能进行了特殊处理。 * 如果使用vararg参数,则不会使用整个vararg数组, * 而是使用vararg数组的第一个参数, * 如下例所示: * <pre class="groovyTestCase"> * def a = { one, two, Object[] others {@code ->} one + two + others.sum() } * assert a.parameterTypes.name == ['java.lang.Object', 'java.lang.Object', '[Ljava.lang.Object;'] * assert a(1,2,3,4) == 10 * def b = a.curry(1) * assert b.parameterTypes.name == ['java.lang.Object', '[Ljava.lang.Object;'] * assert b(2,3,4) == 10 * def c = b.curry(2) * assert c.parameterTypes.name == ['[Ljava.lang.Object;'] * assert c(3,4) == 10 * def d = c.curry(3) * assert d.parameterTypes.name == ['[Ljava.lang.Object;'] * assert d(4) == 10 * def e = d.curry(4) * assert e.parameterTypes.name == ['[Ljava.lang.Object;'] * assert e() == 10 * assert e(5) == 15 * </pre> * * * @param arguments 要绑定的闭包参数 * @return 返回已经绑定参数的新的闭包 */ public Closure<V> curry(final Object... arguments) { return new CurriedClosure<V>(this, arguments); }
代码示例 :
// 定义闭包变量 , 声明两个参数 a, b // 并为闭包指定默认值 def closure5 = { a = 0, b = "Groovy" -> println "${a} : ${b}" } // 闭包有默认值 , 调用时可以不传入参数 closure5() // 从左到右绑定 闭包参数 def closure6 = closure5.curry(1, "Gradle") // 闭包有默认值 , 调用时可以不传入参数 closure6()
执行结果 :
0 : Groovy 1 : Gradle
2、闭包参数绑定 rcurry 函数
闭包参数绑定 rcurry 函数是从右到左绑定参数 , 但是 参数的顺序还是从左到右的顺序 , 这点要注意 ;
闭包参数绑定 rcurry 函数原型 :
/** * 从右到左绑定闭包参数 * 根据普通的 curry()方法,参数在右侧而不是左侧提供。 * 典型用法: * <pre class="groovyTestCase"> * def divide = { a, b {@code ->} a / b } * def halver = divide.rcurry(2) * assert halver(8) == 4 * </pre> * * curried参数的位置将被延迟计算, * 例如,如果有两个重载的doCall方法可用, * 则提供的参数加上curried参数将被连接,结果将用于方法选择。 * * @param arguments 绑定的参数 * @return 绑定参数后的新闭包 * @see #curry(Object...) */ public Closure<V> rcurry(final Object... arguments) { return new CurriedClosure<V>(-arguments.length, this, arguments); }
代码示例 :
// 定义闭包变量 , 声明两个参数 a, b // 并为闭包指定默认值 def closure5 = { a = 0, b = "Groovy" -> println "${a} : ${b}" } // 闭包有默认值 , 调用时可以不传入参数 closure5() // 从右到左绑定 闭包参数 def closure7 =closure5.rcurry(2, "Java") // 闭包有默认值 , 调用时可以不传入参数 closure7()
执行结果 :
0 : Groovy 2 : Java