defer
It is a keyword used in Go language to delay execution of function calls, and is often used for resource cleaning (such as closing files, releasing locks) and exception handling. However, there are some hidden details in its behavior mechanism, and a little carelessness may lead to undetectable bugs. This article uses multiple intuitive examples to analyze in-depthdefer
The core mechanism.
1. Defer execution order: last in first out (LIFO)
Multipledefer
Statement PressReverse execution, similar to the "last in first out" principle of stack.
Example: Execution order of multiple defers
func main() { defer ("defer 1") defer ("defer 2") ("main logic") }
Output:
main logic
defer 2
defer 1
in conclusion:
-
defer
Statements are executed in reverse order in the registration order to ensure that dependent resources are released in the correct order (such as opening the file first and then closing).
2. Pre-calculation of defer’s parameters: the trap of value copy
defer
The parameters of are immediately registeredPre-calculate and copy, not dynamically retrieved during execution.
Example: The impact of parameter precalculation
func main() { x := 10 defer ("x:" in defer, x) // The value of x is copied at registration x = 20 ("x:" in main, x) }
Output:
x: 20 in main
x: 10 in defer
in conclusion:
- If the parameter is a value type (such as
int
、string
),defer
The current value will be copied, and subsequent modifications will not affect the registered ones.defer
。 - If the parameter is a pointer or reference type (such as
*int
、slice
), the copy is the address, and subsequent modifications will affectdefer
The execution result.
3. Defer and closure: dynamically bound variables
defer
If a function uses an external variable (closure), it will refer to the variable.Latest value, not the value at the time of registration.
Example: Variable binding in closure
func main() { x := 10 defer func() { ("x:" in defer, x) // The closure references the latest value }() x = 20 ("x:" in main, x) }
Output:
x: 20 in main
x: 20 in defer
in conclusion:
- The variables in the closure are
defer
The value is evaluated only when executed, so it will reflect the final state of the variable. - If you need to fix the value in the closure, you need to pass it through parameters when registering (such as
defer func(a int) { ... }(x)
)。
4. Defer and return value: implicit assignment logic
defer
The behavior of modifying the return value in depends on how the return value is defined (value returns vs pointer returns).
Example 4: Difference between value return and pointer return
// Value return: Defer modification does not affect the return valuefunc f1() int { x := 10 defer func() { x++ }() return x // What is actually returned is a copy of x} // Pointer return: defer modification affects return valuefunc f2() *int { x := 10 defer func() { x++ }() return &x // Return the address of x} func main() { (f1()) // Output 10 (*f2()) // Output 11}
in conclusion:
-
Value returns: The return value is
return
Copy whendefer
Modifying the original variable will not affect the copied value. -
Pointer return: The variable address is returned.
defer
Modify the original variable through the address to affect the final result.
This is all about this article about the defer mechanism in Go. For more relevant content on Go defer mechanism, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!