Go关键字defer的特性

栏目: IT技术 · 发布时间: 4年前

内容简介:Go里面,流程控制语句中有一个下面用代码说话。

Go里面,流程控制语句中有一个 defer 的关键字,翻译过来就是延迟的意思。

下面用代码说话。

func deferFunc() {
    defer fmt.Println("后打印")
    fmt.Println("先打印")
}

defer 在函数执行完毕之后,才会执行,所以,我们经常在释放资源或异常处理等需要收尾的场景下会用到 defer

不过 defer 也有一些“坑”,大家需要注意一下。

func printNumbers() {
    for i := 0; i < 5; i++ {
        defer func() {
            fmt.Print(i) // 输出55555
        }()
    }
}

上面例子中, defer 是在 for 循环全部执行完毕之后才会执行,所以 i 已经变成了 5 ,正确做法是下面这样

func printNumbers() {
    for i := 0; i < 5; i++ {
        defer func(j int) {
            fmt.Print(j) // 输出43210
        }(i)
    }
}

上面打印的是倒序,这是因为 defer 的执行顺序和栈的特性一样,都是 先进后出

defer 还有一个特性,当函数有参数传入时,那些参数的值会在声明时求出

func printNumbers() {
    for i := 0; i < 5; i++ {
        defer func(j int) {
            fmt.Print(j) // 输出86420
        }(i * 2)
    }
}

上面的例子大家可能看的不是很清楚,下面给过一个例子

func main() {
    i := 2
    defer fmt.Println(i) // 输出2,原因就是上面说的

    i = 8
    fmt.Println(i)
}

上面这个例子就很明显了,后面 i 如何变都不会影响 defer 输出的内容

defer 还有一个经常在面试中提到的问题,就是和 return 的执行顺序,下面是我整理的3个例子

func main() {
    fmt.Println("a return: ", a())
    fmt.Println("b return: ", b())
    fmt.Println("c return: ", *c())
}

func a() int {
    var i int

    defer func() {
        i = 1
        fmt.Println("a defer i: ", i)
    }()

    return i
}

func b() (i int) {
    defer func() {
        i = 2
        fmt.Println("b defer i: ", i)
    }()

    return i
}

func c() *int {
    var i int
    defer func() {
        i = 3
        fmt.Println("c defer i: ", i)
    }()

    return &i
}
// 输出
a defer i:  1
a return:  0
b defer i:  2
b return:  2
c defer i:  3
c return:  3

原因网上有很多优秀的解释,我就再说一下我的理解

  • a 函数之所以返回 0 ,是因为返回值是无名的, returni 的值写入返回值后, defer 再修改 i 的值,但是已经影响不到返回值了
  • b 函数之所以返回 1 ,是因为返回值已经声明成 i 了, return 之后, deferi 修改自然就影响了return的返回值了
  • c 函数结果和 a 函数不一样,是因为返回值是指针类型,一样的道理,返回值改不了,但是返回值指向的值已经更改,所以就有上面的结果

正常工作里面,虽然不可能写这种代码,但是面试的时候这些基础问题出现的频率还是挺高的,所以大家也是需要掌握一下。融汇贯通,自己多操作多试试,加深印象。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

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

Python编程实战

Python编程实战

[美] Mark Summerfield / 爱飞翔 / 机械工业出版社 / 2014-8 / 69.00元

《python编程实战:运用设计模式、并发和程序库创建高质量程序》由python开发者社区知名技术专家mark summerfield亲笔撰写,全球资深python专家doug hellmann作序鼎力推荐,是python领域最有影响力的著作之一。书中通过大量实用的范例代码和三个完整的案例研究,全面而系统地讲解了如何运用设计模式来规划代码结构,如何通过并发与cython等技术提升代码执行速度,以及......一起来看看 《Python编程实战》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

html转js在线工具
html转js在线工具

html转js在线工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具