golang 中的闭包和defer

栏目: Go · 发布时间: 5年前

内容简介:golang中的defer和闭包对很多初学者来说,有时候有很多坑,但是很多介绍的文章有写的乱七八糟.放假了没事可干,就稍微总结一下.闭包有叫匿名函数,使用闭包可以使我们的代码更加优雅简洁,顾名思义匿名函数就是没有名字的函数.注意上面的代码,上面的代码输出

golang中的defer和闭包对很多初学者来说,有时候有很多坑,但是很多介绍的文章有写的乱七八糟.放假了没事可干,就稍微总结一下.

闭包

闭包有叫匿名函数,使用闭包可以使我们的代码更加优雅简洁,顾名思义匿名函数就是没有名字的函数.

func test() int {
    var i int
    f:=func() {
        time.Sleep(1*time.Second)
        i += 1 //闭包是通过指针传递的,所以对i的修改相当于修改指针指向的内容.
        fmt.Println(" i:", i)
    }
    f()
    f()
    fmt.Println(i)
    return i
}

注意上面的代码,上面的代码输出

i: 1
 i: 2
2
2

因为闭包中对a中的变量i是通过指针传递的,所以闭包里面对i的修改会直接修改i的值.

defer

func a() int {
    var i int
    defer add(i) //这里虽然defer是在return之前执行,但是在定义的时候,
    // 已经将defer要执行的函数压入栈,所以传递给add的是var i int的i值.
        /*defer func(){
        add(i)
    }() */
    i += 100
    return i //return  0
}
func b() int {
    var i int
    defer func(){
        add(i)
    }()
    i += 100
    return i //return  0
}
 add(i int)  {
    i += 1
    fmt.Println(i)
    
}

分别考虑一下a b 函数的输出

这里会产生不同是因为,如果你在定义defer的时候,就要将defer后面的函数参数等入栈,等到ruturn之前的时候出栈执行,a中是将i的拷贝直接入栈,b中通过一个闭包调用,实际上将i的指针传递给闭包,闭包读取值拷贝给add.

另外我们经常说defer定义的顺序跟执行的顺序相反也是因为栈中先入后出的原因.

返回值

上面主要说了defer 和闭包,defer 容易让人混淆的地方其实是在处理返回值的时候.

func d() (i int) {
    i = 100
    defer func() {
        i += 1
    }()
    return 5 // 这里返回之前相当于 i=5 执行defer return i,所以defer中通过闭包给i++ 相当于{i=5 ,i++,return i}
}

func b() int {
    var i int
    defer func() {
        i += 1
    
    }()
    i += 100

    return i //这里相当于a=i defer return a 所以defer中闭包i++ 相当于{a=i i++ return a}
}

考虑一下上面2个函数的返回值,

b函数中返回retrun i 这个语句相当于如下

  • a=i(这里i值为100) //因为没有定义返回值名,会定义一个int 的值保存i返回.
  • defer定义的函数出栈,然后执行.在b中通过闭包对i进行了+1
  • return a
    所以返回值是100而不是101,因为在第一步a的值是100
    d 函数中return 5 这个语句相当于如下
  • i=5 //因为d函数中定义了返回值i
  • defer定义的函数出栈,然后执行.在b中通过闭包对i进行了+1
  • return i
    所以返回值是6而不是5.

总结

其实理解defer 闭包这些只要理解以下几点就会彻底明白

  1. 闭包是通过指针操作母函数中的变量
  2. defer 定义的过程就相当生成一个函数体然后将它压入栈,等到return的时候出栈执行
  3. defer 执行是在return 之前执行。这里要注意的是如果没有声明返回变量,需要先声明一个返回值然后赋值给它返回。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Designing for Emotion

Designing for Emotion

Aarron Walter / Happy Cog / 2011-10-18 / USD 18.00

Make your users fall in love with your site via the precepts packed into this brief, charming book by MailChimp user experience design lead Aarron Walter. From classic psychology to case studies, high......一起来看看 《Designing for Emotion》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

随机密码生成器
随机密码生成器

多种字符组合密码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具