Explaining the execution order of go's defer and return in detail
go's defer and return are two keywords in golang, return is used to return the return value of the function, you can also participate in certain process control, such as the following code, return short-circuits the output of the latter
package main import "fmt" // The details of defer and return func main() { foo(2) foo(1) } func foo(i int) { (i) if i == 1 { return } (i + 1) }
Results:
2
3
1
The first output outputs i and i+1 in full, the second output is short-circuited and only outputs 1
defer is a delayed call in golang, often used for file stream closure, lock unlocking operations, the operation after the defer will be called after the end of the current function or goroutine
package main import "fmt" // The details of defer and return func main() { foo() } func foo() { defer ("println defer") ("println foo") } exports: println foo println defer
Defer itself has some characteristics, such as the order of execution between defer and defer is first in, first out, first defer the last execution, analyze the following code:
package main import "fmt" // The details of defer and return func main() { foo() } func foo() { defer ("floor 3") defer ("floor 2") ("floor 1") } exports: floor 1 floor 2 floor 3
According to this feature, if there is a possibility of panic in the code of our defer call, in order to keep the system running, we should recover before rather than after the
ackage main import "fmt" // The details of defer and return func main() { foo() } func foo() { defer func() { panic("panic test") }() defer func() { if err := recover(); err != nil { ("catch panic:", err) } }() } exports: panic: panic test
package main import "fmt" // The details of defer and return func main() { foo() } func foo() { defer func() { if err := recover(); err != nil { ("catch panic:", err) } }() defer func() { panic("panic test") }() } exports: catch panic: panic test
Interaction of defer and return
The interplay between defer and return is mainly expressed in the return value, consider the following code and what the output should be:
import "fmt" // The details of defer and return func main() { (foo1()) (foo2()) (foo3()) } func foo1() int { i := 1 defer func() { i++ }() return i } func foo2() (i int) { i = 1 defer func() { i++ }() return i } func foo3() (i int) { defer func() { i++ }() return 1 }
Output:
1
2
2
The reasons for the above are
existfoo1
function.defer
The closure in the statement will be executed after the function returns, but at that point the return value has been determined to be the1
so it ends up returning1
。
existfoo2
function that uses the named return valuei
。defer
The closure in the statement modifies this named return value, so it returns the2
。
existfoo3
function, which also uses the named return valuei
,defer
The closure in the statement modifies this named return value, and the function returns directly to the1
Libyan Arab Jamahiriyadefer
The changes in2
。
And another feature of return that affects the order in which the code in return and defer is executed
package main import "fmt" // The details of defer and return func main() { (foo1()) } func foo1() int { defer func() { ("This is defer") }() return func() int { ("This is return") return 1 }() } exports: This is return This is defer 1
The reason for the above output is that return is non-atomic, defer will be executed before the return return value, but the statements in the return, will be executed in their entirety until the return anchors a value or names the return value, then the defer statement will be executed, and finally this value anchored by the return will be returned
to this article on a detailed explanation of go defer and return order of execution of the article is introduced to this, more related to go defer and return order of execution of the content please search for my previous articles or continue to browse the following related articles I hope you will support me in the future more!