• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    深入理解Go语言中的闭包

    闭包

    在函数编程中经常用到闭包,闭包是什?它是怎么产生的及用来解决什么问题呢?先给出闭包的字面定义:闭包是由函数及其相关引用环境组合而成的实体(即:闭包=函数+引用环境)。这个从字面上很难理解,特别对于一直使用命令式语言进行编程的程序员们。

    Go语言中的闭包

    先看一个demo:

    func f(i int) func() int {
     return func() int {
     i++
     return i
     }
    }

    函数f返回了一个函数,返回的这个函数就是一个闭包。这个函数中本身是没有定义变量i的,而是引用了它所在的环境(函数f)中的变量i。

    我们再看一下效果:

    c1 := f(0)
    c2 := f(0)
    c1() // reference to i, i = 0, return 1
    c2() // reference to another i, i = 0, return 1

    c1跟c2引用的是不同的环境,在调用i++时修改的不是同一个i,因此两次的输出都是1。函数f每进入一次,就形成了一个新的环境,对应的闭包中,函数都是同一个函数,环境却是引用不同的环境。

    变量i是函数f中的局部变量,假设这个变量是在函数f的栈中分配的,是不可以的。因为函数f返回以后,对应的栈就失效了,f返回的那个函数中变量i就引用一个失效的位置了。所以闭包的环境中引用的变量不能够在栈上分配。

    escape analyze

    在继续研究闭包的实现之前,先看一看Go的一个语言特性:

    func f() *Cursor {
     var c Cursor
     c.X = 500
     noinline()
     return c
    }

    Cursor是一个结构体,这种写法在C语言中是不允许的,因为变量c是在栈上分配的,当函数f返回后c的空间就失效了。但是,在Go语言规范中有说明,这种写法在Go语言中合法的。语言会自动地识别出这种情况并在堆上分配c的内存,而不是函数f的栈上。

    为了验证这一点,可以观察函数f生成的汇编代码:

    MOVQ $type."".Cursor+0(SB),(SP) // 取变量c的类型,也就是Cursor
    PCDATA $0,$16
    PCDATA $1,$0
    CALL ,runtime.new(SB) // 调用new函数,相当于new(Cursor)
    PCDATA $0,$-1
    MOVQ 8(SP),AX // 取c.X的地址放到AX寄存器
    MOVQ $500,(AX) // 将AX存放的内存地址的值赋为500
    MOVQ AX,"".~r0+24(FP)
    ADDQ $16,SP

    识别出变量需要在堆上分配,是由编译器的一种叫escape analyze的技术实现的。

    如果输入命令:

    go build --gcflags=-m main.go

    可以看到输出:

    注意:最后两行,标识c逃逸了,被移动到堆中。escape analyze可以分析出变量的作用范围,这是对垃圾回收很重要的一项技术。

    总结

    以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

    您可能感兴趣的文章:
    • GO语io包的常用接口
    • Go语言的os包中常用函数初步归纳
    • 举例讲解Go语言中函数的闭包使用
    • go语言里包的用法实例
    • Go语言声明一个多行字符串的变量
    • Go语言基础知识总结(语法、变量、数值类型、表达式、控制结构等)
    • GO语言获取系统环境变量的方法
    • Go语言中的变量声明和赋值
    • 详解Golang编程中的常量与变量
    • go语言学习之包和变量详解
    上一篇:深入理解Go语言中的Dispatcher
    下一篇:golang实现sql结果集以json格式输出的方法
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    深入理解Go语言中的闭包 深入,理解,语言,中的,闭包,