GO语言学习之defer延迟调用

Go里的流程控制如下:

  • if - else条件语句
  • swich - case选择语句
  • for - range 循环语句
  • goto无条件跳转语句
  • defer延迟执行

1.延迟调用

defer的用法很简单,只要在后面跟一个函数的调用,就能实现将这个xxx函数的调用延迟到当前函数执行完后再执行

defer xxx() 

这是一个很简单的例子,可以快速理解defer的使用效果

import "fmt"

func myfunc() {
    fmt.Println("B")
}

func main() {
    defer myfunc()
    fmt.Println("A")
}    

输出如下

A
B

也可以简写成如下,输出结果是一致的

import "fmt"

func main() {
    defer fmt.Println("B")
    fmt.Println("A")
}

2.即时求值的变量快照

使用defer只是延迟调用函数,此时传递给函数里的变量,不应该收到后续程序的影响

import "fmt"

func main() {
    name := "go"
    defer fmt.Println(name) // 输出: go

    name = "python"
    fmt.Println(name)      // 输出: python
}

输出如下,可见给 name 重新赋值为 python,后续调用 defer 的时候,仍然使用未重新赋值的变量值,就好像在 defer 这里,给所有的变量做了一个快照一样

python
go

3.为什么要有defer

若是没有 defer,你可能这样写代码

func f() {
    r := getResource()  //0,获取资源
    ......
    if ... {
        r.release()  //1,释放资源
        return
    }
    ......
    if ... {
        r.release()  //2,释放资源
        return
    }
    ......
    if ... {
        r.release()  //3,释放资源
        return
    }
    ......
    r.release()     //4,释放资源
    return
}

使用了 defer 后,代码就显得简单直接了,不管你在何处 return,都会执行 defer 后的函数

func f() {
    r := getResource()  //0,获取资源

    defer r.release()  //1,释放资源
    ......
    if ... {
        ...
        return
    }
    ......
    if ... {
        ...
        return
    }
    ......
    if ... {
        ...
        return
    }
    ......
    return
}

 

posted @ 2020-10-27 16:56  差点点温柔  阅读(168)  评论(0编辑  收藏  举报