In the previous article, we used defer
to recover from panics. In the practical work of a gopher, defer
acts like a loyal and reliable teammate, silently helping us with the clean-up work behind the scenes. For example:
This article is first published in the medium MPP plan. If you are a medium user, please follow me in medium. Thank you very much.
|
|
defer
is used to release locks or any other resources.
In Go,
defer
can only be used inside functions and methods.
Thedefer
keyword must be followed by a function or method, which are referred to as deferred functions.
defer
registers these functions into a stack data structure specific to the goroutine in which it is executed. The deferred functions are then scheduled to be executed in a last-in, first-out (LIFO) order before the function containing the defer
statement exits.
Regardless of whether the function reaches the end of its body and returns, explicitly calls return
in an error handling branch, or encounters a panic, the functions stored in the deferred function stack will be scheduled for execution. Thus, deferred functions provide a convenient way to perform clean-up tasks for a function in any scenario.
Several Use Cases for defer
- Capturing panics: Since deferred functions are always executed in any scenario, we can handle exceptions within
defer
(although it is not recommended to usepanic
for general errors unless necessary). - Resource release:
defer
allows for graceful resource release, such as file descriptors or locks. - Delayed execution:
defer
can be used to record the execution time of a function, for example:
|
|
Performance Overhead of defer
defer
makes resource release (like file descriptors or locks) more elegant and less error-prone. However, in performance-sensitive programs, Gophers must be aware of and consider the performance burden introduced by defer
.
In the following benchmark test, we can observe the performance difference between a version with defer
and a version without defer
:
|
|
In this test, the non-deferred version is approximately 7 times faster than the version with defer
in Go 1.12. After optimization in versions 1.13 and 1.14, the performance of defer
has significantly improved. On my computer, the non-deferred version still has a performance advantage of about 50%.
Conclusion
In most cases, our programs are not highly sensitive to performance. I recommend using defer
whenever possible. However, it is important to understand how defer
works, as well as a few things to avoid.