【Go语音核心编程】-- 闭包

闭包

阅读《Go语音核心编程》一书的时候,看到闭包这个概念,觉得文中讲解的不是很容易理解。因此,想自己结合网上可以查找到的资料,对其进行一次梳理。

概念

这里先转述一下书中的概念:

  • 定义:闭包是由函数及其相关引用环境组合而成的实体,一般通过在匿名函数中引用外部函数的局部变量或者全局变量构成

但是看完之后,并不是特别清晰。这里使用书中的例子说一下自己的理解:

package main

import "fmt"

func fa(a int) func(i int) int {
    return func(i int) int {
       fmt.Println(&a, a)
       a = a + i
       return a
    }
}

func main() {
    f := fa(1) //f 引用的外部的闭包环境包括本次函数调用的形参a 的值 1 ,out:0xc000096068 1
    g := fa(1) //g 引用的外部的闭包环境包括本次函数调用的形参a 的值 1,out:0xc00000a0d0 1
    // 此时 f,g 引用的闭包环境中的 a 的值并不是同一个,而是两次函数调用产生的副本
    fmt.Println(f(1))//,out:0xc000096068 1,2
    //多次调用 f 引用的是同一个副本 a,所以这里就会是 3
    fmt.Println(f(1))//,out:0xc000096068 2,3
    //g 的 a 的值仍然是 1
    fmt.Println(g(1))//,out:0xc00000a0d0 1,2
    fmt.Println(g(1))//,out:0xc00000a0d0 2,3
}

简单理解,其实就是在一个函数(fa)内部创建另外一个函数(return func(i int)),通过另一个函数访问这个函数的局部变量 a。

第一次调用fa,fa 函数执行完退出,其中的匿名函数存储了变量 a,所以 a 并没有被销毁。因此,后续调用 f 的时候,依旧可以访问并且修改 a。相对于 f 来说,其实就是讲函数内部和函数外部连接起来。

需要注意的是,如果闭包引用修改了全局变量,那么每次调用都会影响全局变量。(这个需要避免,而且闭包的最初目的,就是为了减少全局变量)

闭包的优缺点

  • 优点:
    • 延长了变量的生命周期(fa 函数销毁之后,依旧可以修改 a 变量)
    • 延迟执行:在需要在函数执行结束后再执行某些操作时非常有用,比如资源清理、释放等。
    • 回调函数
  • 缺点:
    • 资源泄露: 闭包中捕获的外部变量可能导致资源泄露。
    • 性能损耗: 闭包的实现可能会导致一定的性能损耗。需要在堆上分配内存来保存捕获的变量,相比普通函数,闭包可能会有更多的内存分配和垃圾回收开销。
    • 代码可读性: 使用过度复杂的闭包可能会降低代码的可读性和可维护性。
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jiangw557

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值