Introduction to go defer (go delay function)

Release: 2019-11-30 14:03:38
forward
2300 people have browsed it

Introduction to go defer (go delay function)

Go language's defer is considered a new feature of the language, at least compared to today's mainstream programming languages.

The defer statement calls a function. The execution of this function will be postponed until the peripheral function returns, or the peripheral function runs to the end, or the corresponding goroutine panics

Whenever defer is executed, it The subsequent function value (in Go, the function is a reference type, a first-class citizen, and can be assigned to a variable) and function parameters will be evaluated, but the function will not be called immediately until (↑) the above three situations occur. This is the whole content of defer, gone, the rest is the best practice of defer

The function will not be called immediately

Start with the simplest one:

func readFile(fileName string){
    f,err := os.Open(fileName)
    if err!=nil {
        return
    }
    defer f.Close()
    var content [1024]byte
    f.Read(content[:])
    fmt.Printf("%s",content)
}
func main() {
    readFile("test.data")
}
Copy after login

The program outputs the first 1024 bytes of test.data. It is worth mentioning that open/close pairing operations like this are the idiomatic usage of defer. This example explains the second half of the above sentence

"But the function will not be called"

Because if f.Close() after defer is not delayed, then the file descriptor If they are all closed, nothing will be read.

The function value and function parameters are evaluated, but the function is not called immediately

The following example will explain the first half, it comes from <>, slightly Modification:

func trace(funcName string) func(){
    start := time.Now()
    fmt.Printf("function %s enter\n",funcName)
    return func(){
        log.Printf("function %s exit (elapsed %s)",funcName,time.Since(start))
    }
}
 
func foo(){
    defer trace("foo()")()
    time.Sleep(5*time.Second)
}
func main(){
    foo()
    foo()
}
/*
OUTPUT:
function foo() enter
function foo() exit (elapsed 5.0095471s)
function foo() enter
function foo() exit (elapsed 5.0005382s)
*/
Copy after login

Why does foo output enter and then wait for about five seconds before outputting exit? Because as we said, the function value and parameters after

defer will be evaluated but the actual function The call has to wait until the end

The function value here is the anonymous function returned by trace(). The function parameter is of course the string literal value "foo()". The evaluation of trace("foo()") will Output function foo() enter, the actual function call trace("foo()")(), that is, the output function foo() exit(elapsed x.x) will be postponed until return execution (if return will update the return value variable, it will be executed after the update before executing the defer function).

Miscellaneous

To say a little more, if there are multiple defer statements, the execution order of the last defer function is opposite to the order in which defer appears, such as:

func main() {
    func1 := func(){
        fmt.Println("func1() execution deferred")
    }
    func2 := func(){
        fmt.Println("func2() execution deferred")
    }
    defer func1()
    defer func2()
    fmt.Println("strat\nworking...")
}
/*
OUTPUT:
strat
working...
func2() execution deferred
func1() execution deferred
*/
Copy after login

The above is the detailed content of Introduction to go defer (go delay function). For more information, please follow other related articles on the PHP Chinese website!

Related labels:
go
source:cnblogs.com
Statement of this Website
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
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template