• golang闭包的一个经典例子


    转自原文链接
    https://www.golangtc.com/t/50d07e11320b521f59000012

    闭包虽然在开发中用得不多,但是理解意义还是对于编程有帮助的
    版本1:

    package main
    
    import "fmt"
    
    func main() {
    
        var fn [10]func()
    
        for i := 0; i < len(fn); i++ {
            fn[i] = func() {
                fmt.Println(i)
            }
        }
    
        for _, f := range fn {
            f()
        }
    }
    

    结果如下:

    10
    10
    10
    10
    10
    10
    10
    10
    10
    10
    

    分析:mian()与func()[]数组构成闭包使用同一个i变量main函数不退出i变量一直存在,f()执行时调用打印语句此时变量i为10。 版本2:

    package main
    
    import "fmt"
    
    func main() {
    
        var fn [10]func()
    
        for i := 0; i < len(fn); i++ {
            fn[i] = func() {
                fmt.Println(i)
            }
        }
    
        for i := 0 ; i < len(fn); i++ {
            fn[i]()
        }
    }
    

    结果如下:

    10
    10
    10
    10
    10
    10
    10
    10
    10
    10
    

    分析:与版本1对比使用显示的i变量做为迭代,但是闭包空间中的i与调用迭代中的i指向内存不同(生存空间也不同)所以使用闭包空间中的i作为打印值为10。 版本3:

    package main
    
    import "fmt"
    
    func main() {
    
        var fn [10]func()
    
        for i := 0; i < len(fn); i++ {
            fn[i] = func() {
                fmt.Println(i)
            }
        }
    
        for j := 0 ; j < len(fn); j++ {
            fn[j]()
        }
    }
    

    结果如下:

    10
    10
    10
    10
    10
    10
    10
    10
    10
    10
    

    分析:为证明版本2中的分析说法,使用j作为迭代变量,同样打印的10. 版本4:

    package main
    
    import "fmt"
    
    func main() {
    
        var fn [10]func()
        var i int
    
        for i = 0; i < len(fn); i++ {
            fn[i] = func() {
                fmt.Println(i)
            }
        }
    
        for i = 0; i < len(fn); i++ {
            fn[i]()
        }
    }
    

    结果如下:

    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    

    分析:在main()中声明变量i此时i的生存空间扩大到了main()函数,两次迭代使用同一个i变量。故在第二次迭代时i的迭代当前值会作为打印参数。 版本5:

    package main
    
    import "fmt"
    
    func main() {
    
        var fn [10]func()
    
        for i := 0; i < len(fn); i++ { 
            fn[i] = make_fn(i)
        }
    
        for _, f := range fn {
            f()
        }
    }
    
    func make_fn(i int) func() {
        return func() {
            fmt.Println(i)
        }
    }
    

    结果如下:

    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    

    分析:在main()函数外定义单独的闭包函数,构成独立的闭包单元,隔离不同func()[]中不同的func()。隔离与独立才是闭包的意义所在,一个表示一系列状态的集合不该在外部为显示通知改变时改变其内部状态。 版本6:

    package main
    
    import "fmt"
    
    func main() {
    
        var fn [10]func(int)
    
        for i := 0; i < len(fn); i++ { 
            fn[i] = make_fn()
        }
    
        for i, f := range fn {
            f(i)
        }
    }
    
    func make_fn() func(i int) {
        return func(i int) {
            fmt.Println(i)
        }
    }
    

    结果如下:

    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    

    分析:最后这个版本应该为最佳,gotour中的闭包示例使用的正是此中表示方式。

  • 相关阅读:
    【就业】腾讯VS百度
    MySQL基础知识
    PHP读取远程文件并保存
    【GTK3.0】背景设置
    【GTK】信号量(signal)大全
    c# 调用win32 api
    PHP写窗体程序
    一个苏州IT人的5年挨踢经历面试篇(之二)
    【c++ Primer 】 4.10复习题 12题(int)、(int&)和(int*)
    线段树技巧
  • 原文地址:https://www.cnblogs.com/hirampeng/p/11279898.html
Copyright © 2020-2023  润新知