Go语言defer语句的用法
Go语言除了传统的流程控制语句外,还有一些特殊的控制语句,defer 就是其中之一。
defer 主要用于延迟调用指定的函数,defer 关键字只能出现在函数的内部,例如:
hello
world
在以上代码中会首先打印 hello,然后打印 world,因为第一句使用了 defer 关键字,defer 语句会在函数最后执行,被延迟的操作是 defer 后面的内容。
defer 后面的表达式必须是外部函数的调用,上面的例子就是针对 fmt.Println 函数的延迟调用。
Go语言 defer 语句有如下两大特点:
因为 defer 的延迟特点,可以把 defer 语句用于回收资源、清理收尾等工作。使用 deter 语句之后,不用纠结回收代码放在哪里,反正都是最后执行。
这里需要注意 defer 的执行时机,例如:
5
5
5
5
5
在以上代码中,返回了 5 个 5,这是因为每个 defer 都是在函数轮询之后才执行,此时 i 的值为 5。
如需要正确反向打印数字,Go语言代码如下:
4
3
2
1
0
当 i 等于 0 时,defer 语句第一次被压栈,此时 defer 后面的函数返回 0;i 不断自增,一直到 i 等于 4 时,defer 语句第 5 次入栈,defer 后的函数返回 4;此时 i 的自增不再满足 for 条件,于是跳出循环,在结束之前,Go语言会根据 defer 后进先出原则逐条打印栈内的数值,因此就看到了现在的结果。
defer 主要用于延迟调用指定的函数,defer 关键字只能出现在函数的内部,例如:
package main import "fmt" func main() { defer fmt.Println("world") fmt.Println("hello") }运行结果如下:
hello
world
在以上代码中会首先打印 hello,然后打印 world,因为第一句使用了 defer 关键字,defer 语句会在函数最后执行,被延迟的操作是 defer 后面的内容。
defer 后面的表达式必须是外部函数的调用,上面的例子就是针对 fmt.Println 函数的延迟调用。
Go语言 defer 语句有如下两大特点:
- 只有当 defer 语句全部执行,defer 所在函数才算真正结束执行。
- 当函数中有 defer 语句时,需要等待所有 defer 语句执行完毕,才会执行 return 语句。
因为 defer 的延迟特点,可以把 defer 语句用于回收资源、清理收尾等工作。使用 deter 语句之后,不用纠结回收代码放在哪里,反正都是最后执行。
这里需要注意 defer 的执行时机,例如:
package main import "fmt" var i = 0 func print() { fmt.Println(i) } func main() { for ; i < 5; i++ { defer print() } }运行结果如下:
5
5
5
5
5
在以上代码中,返回了 5 个 5,这是因为每个 defer 都是在函数轮询之后才执行,此时 i 的值为 5。
如需要正确反向打印数字,Go语言代码如下:
package main import "fmt" var i = 0 func print(i int) { fmt.Println(i) } func main() { for ; i < 5; i++ { defer print(i) } }运行结果如下:
4
3
2
1
0
当 i 等于 0 时,defer 语句第一次被压栈,此时 defer 后面的函数返回 0;i 不断自增,一直到 i 等于 4 时,defer 语句第 5 次入栈,defer 后的函数返回 4;此时 i 的自增不再满足 for 条件,于是跳出循环,在结束之前,Go语言会根据 defer 后进先出原则逐条打印栈内的数值,因此就看到了现在的结果。