Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the defer delay function in go language

2025-04-10 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/02 Report--

This article introduces the knowledge of "what is the defer delay function in go language". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

There is a defer keyword in the Go language, which is often used to implement a delay function to ensure the final execution of critical code. As the saying goes, "be prepared in advance."

Delay function is such a mechanism, no matter whether the program returns normally or reports an exception, as long as there is a delay function to ensure the final execution of this key logic, so it is more appropriate to do some resource cleaning and other operations.

Go in and out in pairs with a beginning and an end

In daily development and programming, some operations always appear in pairs, where there is a beginning, there is an end, where there is an opening, there is a close, and there are some continuous dependencies, and so on.

Generally speaking, we need to control the closing statement, control the closing statement at the right position and time, manually ensure the beginning and end of the whole program, and do not miss the closing operation.

The most common process for copying files is as follows:

Open source files

SrcFile, err: = os.Open ("fib.txt") if err! = nil {t.Error (err) return}

Create a target file

DstFile, err: = os.Create ("fib.txt.bak") if err! = nil {t.Error (err) return}

Copy the source file to the target file

Io.Copy (dstFile, srcFile)

Close the target file

DstFile.Close () srcFile.Close ()

Close the source file

SrcFile.Close ()

It is worth noting that this operation of copying files requires special attention to the order of operations and do not forget to release resources, such as opening and closing first!

Func TestCopyFileWithoutDefer (t * testing.T) {srcFile, err: = os.Open ("fib.txt") if err! = nil {t.Error (err) return} dstFile Err: = os.Create ("fib.txt.bak") if err! = nil {t.Error (err) return} io.Copy (dstFile, srcFile) dstFile.Close () srcFile.Close ()}

> "Snow Dream Technology Post Station": the logic of the above code is still clear and simple, and you may not forget to release resources to ensure the operation order, but if the logic code is more complex, it will be difficult to implement!

Perhaps to simplify the logic of similar code, the Go language introduced the defer keyword and created the concept of delay function.

File copy without defer

Func TestCopyFileWithoutDefer (t * testing.T) {if srcFile, err: = os.Open ("fib.txt"); err! = nil {t.Error (err) return} else {if dstFile,err: = os.Create ("fib.txt.bak") Err! = nil {t.Error (err) return} else {io.Copy (dstFile,srcFile) dstFile.Close () srcFile.Close ()}

There is a copy of the defer file

Func TestCopyFileWithDefer (t * testing.T) {if srcFile, err: = os.Open ("fib.txt"); err! = nil {t.Error (err) return} else {defer srcFile.Close () if dstFile, err: = os.Create ("fib.txt.bak") Err! = nil {t.Error (err) return} else {defer dstFile.Close () io.Copy (dstFile, srcFile)}

The above sample code simply shows the basic use of the defer keyword. The significant advantage is that Open/Close is a pair of operations, will not forget the Close operation because of writing to the end, and continuous dependence can guarantee the delay time normally.

In short, if there are continuous dependencies within the function, that is, the order of creation is A-> B-> C and the order of destruction is C-> B-> A. This is the most appropriate time to use the defer keyword.

Lazy gospel delay function

For more information on official documents, please see Defer statements

If there is no defer delay function, the normal function works normally:

Func TestFuncWithoutDefer (t * testing.T) {/ / "Snow Dream Technical Post Station": normal order t.Log ("Snow Dream Technical Post Station": normal order) / / 12 t.Log (1) t.Log (2)}

When the defer keyword is added to implement the delay, the original 1 is postponed to 2 instead of the previous 1 / 2 order.

Func TestFuncWithDefer (t * testing.T) {/ / "Snow Dream Technical Post Station": execute the defer code t.Log after the normal sequence has been executed ("" Snow Dream Technical Post Station ": execute the defer code after the normal sequence has been completed") / / 21 defer t.Log (1) t.Log (2)}

If there are multiple defer keywords, the execution order can be imagined, the later the execution first, so as to ensure that the resources are released in the dependency order.

Func TestFuncWithMultipleDefer (t * testing.T) {/ / "Snow Dream Technology Post Station": guess that the underlying data structure of defer may be a stack, first in and then out. T.Log ("Snow Dream Technology Post Station": guess that the underlying data structure of defer implementation may be stack, first in and then out.) / 3 21 defer t.Log (1) defer t.Log (2) t.Log (3)}

I believe you already understand the execution order of multiple defer statements, so test it!

Func TestFuncWithMultipleDeferOrder (t * testing.T) {/ / "Snow Dream Technology Post Station": the underlying implementation data structure of defer is similar to the stack structure, which sequentially flashes and executes multiple defer statements t.Log ("Snow Dream Technology Post Station": the underlying implementation data structure of defer is similar to the stack structure Execute multiple defer statements in turn ") / / 23 1 defer t.Log (1) t.Log (2) defer t.Log (3)}

After a preliminary understanding of the use of the defer delay function, we will interpret the relevant definitions in detail with the documentation.

English original document

> A "defer" statement invokes a function whose execution is deferred to the moment the surrounding function returns,either because the surrounding function executed a return statement,reached the end of its function body,or because the corresponding goroutine is panicking.

Chinese translation document

> the "defer" statement calls a function, and the execution of the function is delayed until the surrounding function returns, because the surrounding function executes a return statement that reaches the end of the function body, or because the corresponding co-program is panicking.

Specifically, the timing of execution of the delay function can be divided into three situations:

Surrounding functions execute return

> because the surrounding function executed a return statement

The t.Log (4) statement after return will not run naturally, and the final output of the program is 321, which indicates that the defer statement will be executed in reverse order before the surrounding functions execute return.

Func funcWithMultipleDeferAndReturn () {defer fmt.Println (1) defer fmt.Println (2) fmt.Println (3) return fmt.Println (4)} func TestFuncWithMultipleDeferAndReturn (t * testing.T) {/ / "Snow Dream Technical Station": the defer delay function is executed in reverse order before the wrapping function normal return. T.Log ("Snow Dream Technical Post Station": the defer delay function will be executed in reverse order before the wrapping function is normal return.) / / 3 21 funcWithMultipleDeferAndReturn ()} the surrounding function reaches the function body

> reached the end of its function body

Before the function body of the surrounding function runs to the end, several defer statements are executed in reverse order, that is, output 3 and then output 21. The output of the final function is 321, that is to say, it is guaranteed to execute the defer delay function before the end without return declaration.

Func funcWithMultipleDeferAndEnd () {defer fmt.Println (1) defer fmt.Println (2) fmt.Println (3)} func TestFuncWithMultipleDeferAndEnd (t * testing.T) {/ / "Snow Dream Technology Station": the defer delay function is executed in reverse order before the enclosing function reaches the end of the function body. T.Log ("Snow Dream Technical Post Station": the defer delay function is executed in reverse order before the wrapping function reaches the end of the function body.) / / 3 21 funcWithMultipleDeferAndEnd ()} the current protocol is panicking

> because the corresponding goroutine is panicking

In case of panic, the surrounding function will also run the previously defined defer statement first, while the subsequent code of panic will not run because there is no special treatment, so the program crashes.

The final output of the function is 3 21 panic, so it seems that the defer delay function is still very dedicated to its duty, although the heart is very flustered, it can still ensure that the old, the weak, the sick and the disabled can retreat first!

Func funcWithMultipleDeferAndPanic () {defer fmt.Println (1) defer fmt.Println (2) fmt.Println (3) panic ("panic") fmt.Println (4)} func TestFuncWithMultipleDeferAndPanic (t * testing.T) {/ / "Snow Dream Technical Station": the defer delay function is executed in reverse order before the enclosing function panic panics. T.Log ("Snow Dream Technical Post Station": the defer delay function is executed in reverse order before the surround function panic panics.) / / 3 21 funcWithMultipleDeferAndPanic ()}

Through the interpretation of the definition of defer delay function and related examples, I believe it is clear what defer delay function is, right?

To put it simply, the delay function is a planning mechanism that helps developers finish the aftermath work in time when programming programs, and make plans in advance to prepare for various situations.

When the surrounding function executes normally until it reaches the end of the function body, if it is found that there is a delay function, it will naturally execute the delay function in reverse order.

When the normal execution of the surrounding function encounters the resume statement ready to be returned to the caller, it will also be executed when there is a delay function, which also meets the need for clean-up.

When the surrounding function runs abnormally and carelessly panic panics, the program has a delay function and will not forget to execute it, and making a plan in advance plays a role.

So whether it is normal operation or abnormal operation, it is always right to make a plan in advance, which is basically foolproof, so you might as well consider the defer delay function?

Application scenario of delay function

Basically, delay function can be used for paired operations, especially when there is a dependency before and after the requested resource, the defer keyword should be used to simplify the processing logic.

Here are two common examples to illustrate the application scenario of delay function.

Open/Close

File operations generally involve opening and opening and closing operations, especially the copy operations between files have a strict order, only need to apply for resources in the order followed by defer to meet the resource release operation.

Func readFileWithDefer (filename string) ([] byte, error) {f, err: = os.Open (filename) if err! = nil {return nil, err} defer f.Close () return ioutil.ReadAll (f)}

Lock/Unlock

Lock application and release is an important mechanism to ensure synchronization. There may be dependencies when you need to apply for multiple lock resources. Try the delay function!

Var mu sync.Mutexvar m = make (map [string] int) func lookupWithDefer (key string) int {mu.Lock () defer mu.Unlock () return m [key]} summary and preview of the next section

Defer delay function is a mechanism to ensure the normal operation of critical logic. If there are multiple delay functions, it will generally run in reverse order, similar to the stack structure.

There are generally three situations in which the delay function can be run:

The surrounding function encounters a return

Func funcWithMultipleDeferAndReturn () {defer fmt.Println (1) defer fmt.Println (2) fmt.Println (3) return fmt.Println (4)}

The end of the body of the surrounding function

Func funcWithMultipleDeferAndEnd () {defer fmt.Println (1) defer fmt.Println (2) fmt.Println (3)}

The current cooperative process is in a panic.

Func funcWithMultipleDeferAndPanic () {defer fmt.Println (1) defer fmt.Println (2) fmt.Println (3) panic ("panic") fmt.Println (4)}

This paper mainly introduces what is the defer delay function, and understands the delay function by interpreting the official documents and supporting the relevant code, but there are some possible puzzles in the delay function.

Readers might as well take a look at the following code to compare their conjectures with the actual running results, and we'll share them next time. Thank you for your reading.

This is the end of func deferFuncWithAnonymousReturnValue () int {var retVal int defer func () {retVal++} () return 0} func deferFuncWithNamedReturnValue () (retVal int) {defer func () {retVal++} () return 0} "what is the defer delay function in go language". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report