Home >Backend Development >Golang >Exception handling method of defer keyword in Golang function

Exception handling method of defer keyword in Golang function

WBOY
WBOYOriginal
2023-05-17 08:22:571745browse

Golang is a relatively emerging, open source and high-performance programming language. One of its features is the defer keyword of functions. This keyword allows us to perform some required operations before the end of the function, such as resource cleanup, log output, etc. It can also be used to handle exceptions, making our code more robust and reliable. This article will deeply explore the application of the defer keyword of Golang functions in exception handling, so that readers can use this feature more skillfully.

1. How to use defer

In Golang, the defer keyword can be used to define a function call, which will be executed after the function ends. The special thing about defer is that it will be executed before the function returns, regardless of whether an exception occurs in the middle of the function. For example:

func demo() {
    defer fmt.Println("defer end.")
    fmt.Println("normal flow.")
}

In the above code, the print statement "normal flow." will be executed before the defer statement "defer fmt.Println("defer end.")".

In addition, if multiple defer statements are used in a function, their execution order is on the stack, and the defer defined later will be executed first. For example:

func demo() {
    defer fmt.Println("defer 1.")
    defer fmt.Println("defer 2.")
    fmt.Println("normal flow.")
}

In the above code, the statement "normal flow." is printed first, then "defer 2.", and finally "defer 1.".

2. Defer exception handling

In addition to normal use, defer can also be used to handle exceptions in the code. An exception is an error that occurs during program running. It may be due to many reasons, such as illegal input, logical errors, or system errors. In Golang, we can handle exceptions through the three keywords panic/defer/recover. Among them, panic will cause an exception; recover will catch the exception and handle it; and defer will perform some necessary cleanup operations after the exception is handled. The following is a practical example to illustrate the use of panic/defer/recover:

func catchError() {
    defer func() {
        if err := recover(); err != nil {
            fmt.Println("recovered from: ", err)
        }
    }()
    fmt.Println("start")
    panic("error occurs!")
    fmt.Println("end")
}

In the above code, we call a function catchError, first print the statement "start", and then use panic to cause An exception is thrown and "error occurs!" is printed. At this time, the program will interrupt and enter the defer defined by the catchError function. In this defer, there is an if statement to determine whether an exception is currently caught. If an exception is caught, fmt.Println will be called and "recovered from:" and exception information err will be output.

This example shows that Golang's panic/defer/recover keyword can be used to handle the program accordingly when an exception occurs in the function. Since the defer keyword will be executed under any circumstances, we can use defer to perform some necessary cleanup operations when an exception occurs in the program, such as closing files, releasing resources, etc.

3. Notes on defer

When we use the defer keyword, we need to pay attention to the following points:

  1. For defer in a loop structure, special Pay attention to the timing of its execution.
func testLoop() {
    for i := 0; i < 5; i++ {
        defer fmt.Println("defer: ",i)
    }
    fmt.Println("test loop done.")
}

In the above code, we use a loop structure for defer testing. We want the defer statement to be executed first at the end of each loop so that we can release the resources used in the loop. But in the above code, since the defer statement is executed in LIFO (last in first out), what we finally print is "test loop done." instead of "defer: 4, defer: 3, ..., defer: 0."How to solve it? One way is to change the code to:

func testLoop() {
    for i := 0; i < 5; i++ {
        defer func(i int) {
            fmt.Println("defer: ", i)
        }(i)
    }
    fmt.Println("test loop done.")
}

This way adds a closure to the defer statement and passes the current i value directly to the closure function so that it can be executed later. Call the correct value. As you can see, after changing the code to this way, we successfully printed "test loop done." and "defer: 4, defer: 3, ..., defer: 0.".

  1. When using defer, we must also pay attention to the performance impact it brings. Because each defer statement increases the overhead of the program. Therefore, the number of times defer is used in a program or function should be controlled within a reasonable range to avoid affecting the performance of the program.
  2. Do not try to modify the parameters in the defer statement because they are calculated when they are defined. In this case, it may bring some unexpected results.
  3. If the keyword defer statement contains the go function, then the goroutine will be called at the end of the function execution and will not affect the execution of the main function.

4. Summary

In Golang, the defer keyword is a very important feature. It can be used to perform function cleanup operations, such as closing files, releasing resources, etc. In addition, when an exception occurs in a function, the defer statement can also play a certain role in catching and handling exceptions. When using defer, we need to master its usage and pay attention to relevant precautions in order to make full use of this feature in program development and make our program more robust and reliable.

The above is the detailed content of Exception handling method of defer keyword in Golang function. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn