go 闭包

作者: 呦丶耍脾气 | 来源:发表于2023-03-04 17:56 被阅读0次

1. 什么是闭包

闭包是由函数和与其相关的引用环境组合而成的实体在实现深约束时,需要创建一个能显式表示引用环境的东西,并将它与相关的子程序捆绑在一起,这样捆绑起来的整体被称为闭包。函数 + 引用环境 = 闭包。

2. 闭包和函数的区别

闭包只是在形式和表现上像函数,但实际上不是函数。具体区别如下:

  • 函数运行时只有一个实例,函数体被定义后就确定了,不会在执行时发生变化。
  • 闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。
  • 函数本身不存储任何信息,只有与引用环境结合后形成的闭包才具有记忆性
  • 函数是编译器静态的概念,而闭包是运行期动态的概念。

3. 使用对比

开发一个简易的计数器

3.1 不使用闭包

package main
import "fmt"

func main() {
    // 从一加到十
    for i := 1; i< 10; i++ {
        counter(i)
    }
}
// 实现计数器
func counter(num int) {
    sum := 0
    sum += num
    fmt.Printf("num: %d  结果: %d \n", num, sum)
}
/**输出:
num: 1  结果: 1 
num: 2  结果: 2 
num: 3  结果: 3 
num: 4  结果: 4 
num: 5  结果: 5 
num: 6  结果: 6 
num: 7  结果: 7 
num: 8  结果: 8 
num: 9  结果: 9 
*/

由上述代码可以看出,for循环每执行一次,sum都会清零,没有实现sum累加计数。

3.2 使用闭包

package main
import "fmt"

func counterByClosure() func(num int) {
    sum := 0
    return func(num int) {
        fmt.Printf("num: %d 相加前 sum = %d  相加后 sum =  %d \n",num,sum,sum+num)
        sum += num
    }
}

func main() {
    // 初始化闭包函数
    counterFunc := counterByClosure()
    fmt.Println(" ---------  再从1加到10 -------- ")
    // 从1加到10
    for i := 1; i<= 10; i++ {
        counterFunc(i)
    }
    fmt.Println(" ---------  再从10加到20 -------- ")
    // 再从10加到20
    for i := 10; i<= 20; i++ {
        counterFunc(i)
    }
}
/**输出:
 ---------  再从1加到10 -------- 
num: 1 相加前 sum = 0  相加后 sum =  1 
num: 2 相加前 sum = 1  相加后 sum =  3 
num: 3 相加前 sum = 3  相加后 sum =  6 
num: 4 相加前 sum = 6  相加后 sum =  10 
num: 5 相加前 sum = 10  相加后 sum =  15 
num: 6 相加前 sum = 15  相加后 sum =  21 
num: 7 相加前 sum = 21  相加后 sum =  28 
num: 8 相加前 sum = 28  相加后 sum =  36 
num: 9 相加前 sum = 36  相加后 sum =  45 
num: 10 相加前 sum = 45  相加后 sum =  55 
 ---------  再从10加到20 -------- 
num: 10 相加前 sum = 55  相加后 sum =  65 
num: 11 相加前 sum = 65  相加后 sum =  76 
num: 12 相加前 sum = 76  相加后 sum =  88 
num: 13 相加前 sum = 88  相加后 sum =  101 
num: 14 相加前 sum = 101  相加后 sum =  115 
num: 15 相加前 sum = 115  相加后 sum =  130 
num: 16 相加前 sum = 130  相加后 sum =  146 
num: 17 相加前 sum = 146  相加后 sum =  163 
num: 18 相加前 sum = 163  相加后 sum =  181 
num: 19 相加前 sum = 181  相加后 sum =  200 
num: 20 相加前 sum = 200  相加后 sum =  220 
*/

由于闭包函数“捕获”了和它在同一作用域的其他常量和变量,所以当闭包在任何地方被调用,闭包都可以使用这些常量或者变量。它不关心这些变量是否已经超出作用域,只要闭包还在使用这些变量,这些变量就依然存在。

4.闭包的优点

  • 加强模块化:闭包有益于模块化编程,便于以简单的方式开发较小的模块,从而提高开发速度和程序的可复用性。和没有使用闭包的程序相比,使用闭包可将模块划分得更小。
  • 抽象: 闭包是数据和行为的组合,这使得闭包具有较好的抽象能力。
  • 简化代码

相关文章

  • 第02天(函数、工程管理)_03

    11_函数类型.go 12_回调函数.go 13_匿名函数和闭包.go 14_闭包捕获外部变量的特点.go 15_...

  • golang

    golang中闭包的问题 熟悉go语言的开发者都知道,go的闭包是可以记录状态的。当我想用闭包来实现保存某一str...

  • go闭包

    这里的函数接受了一个int参数,返回了一个匿名函数。在调用addn时,返回了就是一个函数,需要再次传参调用执行。其...

  • go闭包

    闭包简单的说就是一个匿名函数+外部变量的引用,举例如下 示例一 package main import ( "...

  • go 闭包

    1.闭包的概念闭包并不是什么新奇的概念,它早在高级语言开始发展的年代就产生了。闭包(Closure)是词法闭包(L...

  • go闭包

    Go语言中闭包是引用了自由变量的函数,被引用的自由变量和函数一同存在,即使已经离开了自由变量的环境也不会被释放… ...

  • go 闭包

    基本介绍 闭包就是一个函数和与其相关的引用环境组合的一个整体(实体) 案例: 说明:1、AddUpper是一个函数...

  • go语言 闭包

  • Go之闭包

    闭包(closure): 一个外层函数中,有内层函数,该内层函数中,会操作外层函数的局部变量(外层函数中的参数,或...

  • 26. 函数闭包

    如果非必要,尽量不要在程序中使用闭包。go函数可以是一个闭包。闭包是一个函数值,它引用了函数体之外的变量。这个函数...

网友评论

      本文标题:go 闭包

      本文链接:https://www.haomeiwen.com/subject/anseldtx.html