• 5.4 Go 闭包


    5.4 Go 闭包

    闭包(closure):是由一个函数和其相关的引用环境组合的一个整体。(闭包=函数+引用环境)

    package main
    
    import (
        "fmt"
    )
    
    //是由一个函数和其相关的引用环境组合的一个整体。(闭包=函数+引用环境)
    //函数addUpper返回值是个函数
    //返回值是匿名函数 func(int)int
    func test() func(int) int {
        //定义一个局部变量
        n := 10
        //返回一个匿名函数
        return func(x int) int {
            n += x
            return n
        }
    
    }
    
    /*
    addUpper函数返回了一个匿名函数,这个匿名函数又引用了函数外的变量n,因此匿名函数+n组成了一个整体,形成闭包
    当调用f函数时,n仅仅被初始化一次,因此每次调用形成累计
    
    */
    
    func main() {
        //调用addUpper函数,获取返回值
        f := test()
        //此时f是匿名函数,对其传参调用
        fmt.Println(f(50)) //10+50=60
        fmt.Println(f(20)) //60+20=80
        fmt.Println(f(20)) //80+20=100 同一个f对象,保留了n的值
    
        f1 := test()
        fmt.Println(f1(10))
    }
    

    闭包代码修改

    package main
    
    import (
        "fmt"
    )
    
    //是由一个函数和其相关的引用环境组合的一个整体。(闭包=函数+引用环境)
    //函数addUpper返回值是个函数
    //返回值是匿名函数 func(int)int
    func test() func(int) int {
        //定义一个局部变量
        n := 10
        var str = "oldboy"
        //返回一个匿名函数
        return func(x int) int {
            n += x
            str += string(36) //36对应的
            fmt.Println("此时str值:", str)
            return n
        }
    
    }
    
    /*
    addUpper函数返回了一个匿名函数,这个匿名函数又引用了函数外的变量n,因此匿名函数+n组成了一个整体,形成闭包
    当调用f函数时,n仅仅被初始化一次,因此每次调用形成累计
    
    */
    
    func main() {
        //调用addUpper函数,获取返回值
        f := test()
        //此时f是匿名函数,对其传参调用
        fmt.Println(f(50)) //10+50=60
        fmt.Println(f(20)) //60+20=80
        fmt.Println(f(20)) //80+20=100 同一个f对象,保留了n的值
    
        //新的初始化
        f1 := test()
        fmt.Println(f1(10))
    }
    

    2. 闭包实战

    package main
    
    import (
        "fmt"
        "strings"
    )
    
    /*
    1.makeSuffixFunc函数接收一个文件名后缀,如.png,且返回闭包
    2.调用闭包,传入文件名前缀,如果没有后缀就添加后缀,返回 文件名.png
    3.strings.HasSuffix可以判断指定字符串后缀
    */
    
    func makeSuffixFunc(suffix string) func(string) string {
        //返回值闭包函数
        return func(filename string) string {
            //如果没有xx后缀,执行代码
            if !strings.HasSuffix(filename, suffix) {
                //则字符串拼接
                return filename + suffix
            }
            //否则有后缀名,则直接返回新文件名
            return filename
        }
    }
    
    func main() {
        //f1返回的是闭包函数,对此闭包函数进行功能性使用
        f1 := makeSuffixFunc(".png")
    
        fmt.Println(f1("苍老师"))  //没有后缀
        fmt.Println("小泽老师.png") //有后缀
    }
    

    总结:

    1.makeSuffixFunc函数中的变量suffix和返回值匿名函数,组合成了一个闭包
    2.由于闭包函数保留了上次引用的值suffix,只需要传入一次,即可反复使用
    

    2.1. 函数式编程

    支持将函数作为另一个函数的参数,叫回调函数。

    支持将函数作为另一个函数的返回值。

    package main
    
    import "fmt"
    
    //闭包函数
    //函数体内有局部变量
    
    func adder() func(int) int {
        sum := 0
        //return 的是一个闭包
        return func(v int) int {
            //引用自由变量,sum
            sum += v
            return sum
        }
    }
    
    //递归定义
    type iAdder func(int) (int, iAdder)
    
    //函数式编程写法,函数+常量
    func adder2(base int) iAdder {
        return func(v int) (int, iAdder) {
            return base + v, adder2(base + v)
        }
    }
    
    func main() {
        // a := adder() is trivial and also works.
        a := adder2(0)
        for i := 0; i < 10; i++ {
            var s int
            s, a = a(i)
            fmt.Printf("0 + 1 + ... + %d = %d
    ",
                i, s)
        }
    }
    

    go闭包-斐波那契数列

    package main
    
    import "fmt"
    
    // 1,1,2,3,5,8,13,21,34,55...
    //
    func fibonacci() func() int {
        a, b := 0, 1
        return func() int {
            a, b = b, a+b
            return a
        }
    
    }
    
    func main() {
        f := fibonacci()
        //斐波那契数列
        fmt.Println(f())
        fmt.Println(f())
        fmt.Println(f())
        fmt.Println(f())
        fmt.Println(f())
        fmt.Println(f())
        fmt.Println(f())
        fmt.Println(f())
        fmt.Println(f())
        fmt.Println(f())
    
    }
    

    2.2. python中闭包

    def adder():
        sum = 0
        def f(value):
            nonlocal sum
            sum +=value 
            return sum 
        return f
  • 相关阅读:
    【TJOI2015】弦论 (后缀数组)
    再见,高中;你好,大学
    我亲爱的朋友们
    将容斥系数隐含在式子中的方法
    一个奇妙的斯特林数推导
    CSP2019游记
    CSP2019初赛游记
    NOI2019游记
    老年选手康复训练
    CTS/APIO2019 游记
  • 原文地址:https://www.cnblogs.com/open-yang/p/11256849.html
Copyright © 2020-2023  润新知