前言
大家都晓得Go编程中,假如在函数F里,执行了defer A(),那在函数F失常return之前或者因为panic要完结运行之前,被defer关键字润饰的函数调用A()都会被执行到。
比方上面的2个例子:
test1()会在main完结之前执行
// defer1.go
package main
import (
"fmt"
)
func test1() {
fmt.Println("test")
}
func main() {
fmt.Println("main start")
defer test1()
fmt.Println("main end")
}
这个例子输入的后果是:
main start
main end
test
test1()会在panic之前执行
// defer2.go
package main
import (
"fmt"
)
func test1() {
fmt.Println("test")
}
func test2() {
panic(1)
}
func main() {
fmt.Println("main start")
defer test1()
test2()
fmt.Println("main end")
}
这个例子输入的后果是:
main start
test
panic: 1
goroutine 1 [running]:
main.test2(...)
/path/to/defer2.go:13
main.main()
/path/to/defer2.go:18 +0xb8
exit status 2
问题
如果在函数F里,defer A()这个语句执行了,是否意味着A()这个函数调用肯定会执行?
这里大家能够先脑补一会。
请看上面的例子:
// defer3.go
package main
import (
"fmt"
"os"
)
func test1() {
fmt.Println("test")
}
func main() {
fmt.Println("main start")
defer test1()
fmt.Println("main end")
os.Exit(0)
}
下面的代码运行后果会是怎么样?
论断
下面defer3.go执行的后果是:
main start
main end
被defer的test1()并没有在main完结之前执行。这是为什么呢?
查看os.Exit的阐明如下:
Exit causes the current program to exit with the given status code. Conventionally, code zero indicates success, non-zero an error. The program terminates immediately; deferred functions are not run.
For portability, the status code should be in the range [0, 125].
如果在函数里是因为执行了os.Exit而退出,而不是失常return退出或者panic退出,那程序会立刻进行,被defer的函数调用不会执行。
defer 4准则回顾
defer (fmt.Println(1)) // 编译报错,因为defer前面跟的表达式不能加括号func a() {
i := 0
defer fmt.Println(i) // 最终打印0
i++
return
}func b() {
for i := 0; i < 4; i++ {
defer fmt.Print(i)
}
}// f returns 42
func f() (result int) {
defer func() {
// result is accessed after it was set to 6 by the return statement
result *= 7
}()
return 6
}Each time a "defer" statement executes, the function value and parameters to
the call are evaluated as usual and saved anew but the actual function is not
invoked. Instead, deferred functions are invoked immediately before the
surrounding function returns, in the reverse order they were deferred. That
is, if the surrounding function returns through an explicit return statement,
deferred functions are executed after any result parameters are set by that
return statement but before the function returns to its caller. If a deferred
function value evaluates to nil, execution panics when the function is
invoked, not when the "defer" statement is executed.
代码
相干代码和阐明开源在GitHub:https://github.com/jincheng9/…