当前位置 博文首页 > 残缺的歌的专栏:Groovy (三) 闭包的使用-----极速入门总结

    残缺的歌的专栏:Groovy (三) 闭包的使用-----极速入门总结

    作者:[db:作者] 时间:2021-09-06 16:17

    一、直接摆例子
    /**
     * Created by Administrator on 2016/8/6.
     */
    /**
    * 闭包的使用
    * 避免了代码的冗长,可以辅助创建轻量级可复用的代码片段
    */
    print("\n闭包的使用:")
    def pickEven(n, block) {
        for (int i = 2; i <= n; i += 2) {
            block(i)
        }
        println()
    }
    
    pickEven(6, { print it })
    pickEven(6) { eventNum -> print eventNum }
    
    def totalSelectValues(n, closure) {
        total = 0
        for (i in 1..n) {
            if (closure(i)) {
                total += i
            }
        }
        total//没有显示的return 则返回最后一个
    }
    
    def isOdd = { it % 2 != 0 }
    println totalSelectValues(10, isOdd)
    
    /**
     * 闭包的作用范围:只有在闭包被定义且存在,而不是在被调用时可以访问其状态值
     */
    println("\n闭包的作用范围:")
    def greeting ='Hello'
    def clos ={param -> println "${greeting} ${param}"}
    clos.call("world")
    
    greeting ='Welcome'
    clos.call('Ken')
    
    def demo(clo){
        def greeting = 'Bonjour'
        clo.call('Ken')
    }
    demo(clos)
    
    /**
     * 闭包在实参列表外部
     */
     greeting ='Hello'
     clos ={param -> println "${greeting} ${param}"}
     demo(clo){
         greeting = 'Bonjour'
        clo.call('Ken')
    }
    //demo() clos //报错
    demo() {param -> println "${greeting} ${param}"}
    demo clos
    demo {param -> println "${greeting} ${param}"}
    /**
     * 向闭包传递参数
     * 对于单参数,it是该参数的默认名称
     * 如果多余一个参数,就得一一列出
     */
    println("\n向闭包传递参数:")
    def tellFortune(closure) {
        closure new Date("09/20/2016"), "your day!!"
    }
    
    tellFortune() {
        date, fortune -> println "Fortune for $date id $fortune"
    }
    
    
    /**
     *  update 的用法
     */
    
    def iterate(n, closure) {
        1.upto(n) {
            println "in iterate with value n is ${it}"
            closure(it)
        }
    }
    
    total = 0
    closure = {
        total += it// 每次调用闭包,都会恢复到上一次的total值
        println "in closure value total is ${total}"
    }
    iterate(4, closure)
    
    /**
     * curry 闭包
     * 在多次调用同一个闭包的时候,有一个或者多个实参是相同的,传参就会很枯燥
     * 可以预先绑定某个形参,调用闭包的时候就不必重复为这个闭包提供参数了
     */
    
    def tellFortunes(closure) {
        Date date = new Date("09/20/2016")
    //    closure date,"first"
    //    closure date,"second"
        //postForturn 保存着保存着科里化后的闭包引用,已经绑定了date数据
        postFortune = closure.curry(date)
        postFortune "first"
        postFortune "second"
    }
    
    tellFortunes() {
        date, forturn ->
            println "Fortunes for ${date} is ${forturn}"
    }
    
    /**
     * 动态闭包
     *  1根据闭包是否参在
     *  2参数数目closure.maximumNumberOfParameters
     *  3参数类型closure.paremeterTypes
     */
    def doSomething(closure) {
        if (closure) {
            closure()
        } else {
            println "Using default"
        }
    }
    
    doSomething()
    doSomething() { println "doSomething with closure" }
    
    
    
    /**
     * 使用尾递归编写程序
     * 递归程序转换成迭代过程,提高性能
     *
     * */
    def factorial
    factorial = { int number, int theFcatorial ->
        number == 1 ? theFcatorial : factorial.trampoline(number - 1, number * theFcatorial)
    }.trampoline()
    
    println "factorial 5 value is ${factorial(5, 1)}"
    cs