GO语言中,defer代码块会在函数调用链表中增加一个函数调用,这个函数调用是发生在return 之后的,通常用来释放函数的内部变量。
假设有一个函数,打开文件并对文件进行若干读写,在这种函数中,经常会有提前返回的情况。如果这样的话,就需要关闭正在工作的文件描述符。可能你会写如下的代码:
1 | // 不用defer |
在这个函数中出现了很多的重复代码,而defer语句是可以解决这些问题的,在defer后指定的函数会在函数退出前进行调用。
我们可以通过defer语句,将Close对应的内容放置在Open后面,可以使函数更加可读和健壮。
1 | func ReadWrite() bool { |
我们再来看一个延迟函数的例子:
1 | for i := 0 ; i < 5 ; i++ { |
延迟的函数是按照后进先出(LIFO)的顺序执行的,所以上面for循环的例子会打印:4 3 2 1 0。
利用defer也可以修改返回值,假设正在使用命名结果参数和函数符号,例如下面这个函数:
1 | defer func() { |
或者这个例子,我们更容易理解为什么,以及在哪需要用括号。
1 | defer func(x int) { |
在这个defer匿名函数中,可以访问任何命名返回参数:
1 | func f() (ret int) { |