2020年/01月/03日 首页回退 函数式groovy 原文 闭包语法 d ef closure = { -> } def closureWithArgs = { arg1, arg2 -> println "statements" } def closureWithImplicit = { println it } Closure<?> typedClosure = {-> } 使用闭包 void 'Declaring and executing a closure'() { given: 'a variable and a closure' def x = 1 def c = { -> def y = 1 x + y } when: 'executing the closure' def result = c() then: 'the value should be the expected' result == 2 } 集合中的典型使用 void 'Using closures with collections (I)'() { given: 'a collection of numbers' def numbers = [1, 2, 3, 4] when: 'collecting the double of each of them' def doubledNumbers = numbers.collect { it * 2 } then: doubledNumbers == [2, 4, 6, 8] } 组合 Double calculate3(Integer... numbers) { def twoTimes = { it * 2 } def divideByTen = { it / 10 } def composedFn = twoTimes >> divideByTen return numbers .collect(composedFn) .sum() } void 'Composition: Calculation gets bigger. Composing (I)'() { given: 'two numbers as input' def first = 10 def second = 20 when: 'invoking the function' def result = calculate3(first, second) then: 'the result should be the expected' result == 6 } 科里化 void 'curry(...): partial application'() { given: 'a function taking a certain number of args' def fn1 = { a, b, c -> a + b + c } when: 'producting another functions' def fn2 = fn1.curry(1) def fn3 = fn1.curry(1, 2, 3) then: 'different applications' fn2(4, 5) == 10 fn3() == 6 } 委托策略 OWNER_FIRST OWNER_ONLY DELEGATE_FIRST DELEGATE_ONLY 记忆 void 'Using a memoized closure'() { given: 'a list of words' def words = [\ 'car','peter','maggie', 'ronnie','book','peter', 'road','car','ronnie' ] and: 'building the memoized closure' def md5fromWord = { String word -> println "Word: $word" java.security.MessageDigest .getInstance("MD5") .digest(word.getBytes("UTF-8")) .encodeHex() .toString() }.memoize() when: 'collecting their md5 hashes' def md5Hashes = words.collect(md5fromWord) then: 'checking figures' md5Hashes.size() == 9 md5Hashes.unique().size() == 6 // Word: car // Word: peter // Word: maggie // Word: ronnie // Word: book // Word: road } 互递归 void 'Trampoline: Adding up numbers recursively'() { given: 'a closure prepared to call itself recursively' def sumRecursively sumRecursively = { List<Integer> numbers, aggregator = 0 -> if (!numbers) { return aggregator } else { sumRecursively.trampoline( numbers.tail(), aggregator + numbers.head()) } } when: 'usisng the transformed version of closure' sumRecursively = sumRecursively.trampoline() def result = sumRecursively(1..10000) then: 'we should get the result without the stackoverflow exception' result == 50005000 }