go defer(go延迟函数)介绍


本文摘自php中文网,作者尚,侵删。

Go语言的defer算是一个语言的新特性,至少对比当今主流编程语言如此。

defer语句调用一个函数,这个函数执行会推迟,直到外围的函数返回,或者外围函数运行到最后,或者相应的goroutine panic

每当defer执行的时候,它后面的函数值(在go中函数是一个引用类型,是一等公民,可以赋值给变量)和函数参数会被求值,但是函数不会立即调用,直到(↑)上述三种情况发生。 这就是defer的全部内容,没了,剩下就是defer的best practice

函数不会立即调用

先从最简单的开始:

1

2

3

4

5

6

7

8

9

10

11

12

13

func readFile(fileName string){

    f,err := os.Open(fileName)

    if err!=nil {

        return

    }

    defer f.Close()

    var content [1024]byte

    f.Read(content[:])

    fmt.Printf("%s",content)

}

func main() {

    readFile("test.data")

}

程序输出test.data前1024字节的内容。值得一提的是,类似这种open/close配对操作是defer的惯用法。 这个例子诠释了上面那句话的后半段

"但是函数不会被调用"

因为如果defer后面的f.Close()没有延迟执行,那么文件描述符都关闭了,就不会读取到任何内容。

函数值和函数参数被求值,但函数不会立即调用

下面这个例子即将诠释上半段,它来自<>,稍作修改:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

func trace(funcName string) func(){

    start := time.Now()

    fmt.Printf("function %s enter\n",funcName)

    return func(){

        log.Printf("function %s exit (elapsed %s)",funcName,time.Since(start))

    }

}

  

func foo(){

    defer trace("foo()")()

    time.Sleep(5*time.Second)

}

func main(){

    foo()

    foo()

}

/*

OUTPUT:

function foo() enter

function foo() exit (elapsed 5.0095471s)

function foo() enter

function foo() exit (elapsed 5.0005382s)

*/

为什么foo会输出enter然后等待五秒左右再输出exit? 因为正如我们说的,

阅读剩余部分

相关阅读 >>

手撸Golang 基本数据结构与算法 栈

Golang核心编程

Golang 底层也用 Golang 吗?

Golang base64 斜杠 等号 问题

Go log

基于原论文,我实现了一个更全面的布谷鸟过滤器

Goland解析json获取指定字段内容

Golang 架构设计原则 迪米特法则

什么是量化交易|量化交易平台

值得推荐的五种自动化代码审查工具

更多相关阅读请进入《Go》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...