The defer keyword in Go language is used to perform some specific operations before the function returns. Defer can be regarded as a post-statement that can be used anywhere in the function.
Here is an example of using defer:
func foo() { defer ("Done") ("Hello") }
In the above example, when the function foo is called, it will output "Hello" first, and then output "Done", because "Done" is wrapped in a defer statement and will be executed before the function returns.
If there are multiple defer statements in a function, their execution order is back in and first out, that is, the last defer statement will be executed first, and the first defer statement will be executed last.
For example, there are three defer statements in the following code, and their execution orders are 3, 2, and 1:
func bar() { defer ("1") defer ("2") defer ("3") }
In Go language, the defer keyword can be used in the following application scenarios:
Resource management: Use defer statements to ensure that resources (such as files, network connections, etc.) are closed and released in a timely manner to avoid resource leakage and excessive system resources.
Delay function calls: Defer statements can delay function calls until the current function returns, which is useful in some scenarios where some cleaning or statistical operations are required before the function execution is over.
Error handling: Defer statement can capture and handle some possible errors, ensuring that the program can exit normally and clean up resources when an exception occurs.
Statistics and debugging: Defer statement can record some statistical information or debugging information during function execution, so as to analyze and troubleshoot when needed.
Application Example 1 Handling of error exceptions
func readFile(filename string) (string, error) { file, err := (filename) if err != nil { return "", err } defer func() { if err := (); err != nil { ("Error closing file:", err) } }() content, err := (file) if err != nil { return "", err } return string(content), nil }
In the example above, we used the defer statement after opening the file and placed the code for closing the file in an anonymous function. If an error occurs in the file read operation, this anonymous function will be executed before the function returns, ensuring that the file is closed and any possible resource leakage is avoided.
It should be noted that if function parameters are used in the defer statement, they need to be assigned to the function return value when the defer statement is executed. In the above example, we need to assign the return value of() to the err variable to check whether the file is closed successfully.
Application Example 2 Use in code statistics and debugging
func processRequest(req *) (*, error) { startTime := () defer func() { ("Request processed in %v", (startTime)) }() // Process the request here // ... resp, err := (req) if err != nil { return nil, err } return resp, nil }
In the above example code, we use the defer statement to record the start time of function execution, and then print out the time it takes for function execution before the function returns. This allows easy performance analysis and debugging to optimize code and identify potential performance bottlenecks. When the function returns, the defer statement will be executed, printing out the time-consuming execution of the function. Due to the characteristics of the defer statement, this defer statement will be executed regardless of whether an exception occurs during the execution of the function, ensuring that we can correctly record the execution time of the function.
Application Example 3 Exception handling in HTTP requests
func handleRequest(w , r *) { // Put the code that handles exceptions in the defer statement defer func() { if r := recover(); r != nil { ("Recovered from panic: %v", r) (w, "Internal Server Error", ) } }() // Handle HTTP requests // ... //Exception may occur in the code // ... }
In the above example code, we may have an exception in the code that handles HTTP requests. To ensure that the resource and clean up state can still be released when the exception occurs, we use the defer statement to put the exception handling code in an anonymous function. When an exception occurs, the defer statement will be executed, catch the exception and print out the exception information, and return a 500 error response to the client.
It should be noted that if function parameters are used in the defer statement, they need to be assigned to the function return value when the defer statement is executed. In the above example code, we need to assign the return value of recover() to the r variable to check if an exception has occurred. At the same time, since the exception handling mechanism in Go is used less, special attention should be paid to the handling of exceptions when handling HTTP requests.
Notice
It should be noted that the defer statement should be used with caution, especially in performance-sensitive scenarios. Because defer statements will increase the execution time and memory consumption of the code, especially in high-frequency code execution such as loops and recursions, too many defer statements may affect the performance and stability of the code.
This is the end of this article about the detailed explanation of the specific operations of the Golang Defer keyword. For more related content of the Golang Defer keyword, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!