Golang comprehensive in-depth series of defer

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Objective

We all know that the defer function of the go language is very powerful, it is very convenient for resource management, but if it doesn't work well, there will be a trap, too. The Go language delay function defer acts as the Try...catch, the use is also very simple, then the defer, return, return value, panic between the execution order is what kind of, below we 1.1 points to uncover its mysterious veil! Don't talk more, come and see the introduction.

Defer introduction

The defer statement is used to perform function calls before the function is returned. This definition may seem complex, but it is easy to understand through an example.

package mainimport ("fmt")func finished() {fmt.Println("finished")}func largest() {defer finished()fmt.Println("largest()执行")}func main() {largest()}

That is, the action performed before the Func End (return). Whether defined before or after a normal statement.

Defer also supports invocation of methods.

package mainimport ("fmt")type person struct {firstName stringlastName string}func (p person) fullName() {fmt.Printf("%s %s",p.firstName,p.lastName)}func main() {p := person {firstName: "John",lastName: "Smith",}defer p.fullName()fmt.Printf("Welcome ")}

Ps:defer declares the value of the determined parameter first, and defer defers only its function body

import (      "fmt")func printA(a int) {      fmt.Println("value of a in deferred function", a)}func main() {      a := 5    defer printA(a)    a = 10    fmt.Println("value of a before deferred function call", a)}

When defer is declared, its parameter a value is parsed in real time and does not execute the contents of the function body, so subsequent modifications do not affect the current parameter values.

Validation results:

package mainimport ("fmt""time")func main() {defer P(time.Now())time.Sleep(5*time.Second)fmt.Println("main ", time.Now())}func P(t time.Time) {fmt.Println("defer", t)fmt.Println("P ", time.Now())}

Execution Result:

main  2018-03-16 14:43:25.10348 +0800 CST m=+5.003171200defer 2018-03-16 14:43:20.1033124 +0800 CST m=+0.003003600P  2018-03-16 14:43:25.142031 +0800 CST m=+5.041722200

Defer LIFO

A simple understanding is executed after the defer is declared (the defer statement is executed in reverse order).

package mainimport (      "fmt")func main() {      name := "Naveen"    fmt.Printf("Orignal String: %s\n", string(name))    for _, v := range []rune(name) {        defer fmt.Printf("%c", v)    }}

Output is: Neevan

Order of execution between Defer/return/return values/Panic

Now we analyze their order of execution in two different situations:

1. Return value assignment before returning

2. Check if there are defer and perform

3. Final return carry return value Exit function

First type: Anonymous return value

package mainimport ("fmt")func main() {fmt.Println("a return:", a()) // 打印结果为 a return: 0}func a() int {var i intdefer func() {i++fmt.Println("a defer2:", i) // 打印结果为 a defer2: 2}()defer func() {i++fmt.Println("a defer1:", i) // 打印结果为 a defer1: 1}()return i}

Output Result:

a defer1: 1a defer2: 2a return: 0

Explanation: The anonymous return value is declared before return (for type reason, type 0 value is 0), defer cannot access anonymous return value, so the return value is 0, and defer is the variable I defined before the operation.

Imagine: If the return value here is a pointer type, then will the output change?

Second type: Named return value

package mainimport ("fmt")func main() {fmt.Println("a return:", a()) // 打印结果为 b return: 2}func a() (i int) {defer func() {i++fmt.Println("a defer2:", i) // 打印结果为 b defer2: 2}()defer func() {i++fmt.Println("a defer1:", i) // 打印结果为 b defer1: 1}()return i // 或者直接 return 效果相同}

Output Result:

a defer1: 1a defer2: 2a return: 2

Explanation: The named return value is declared at the same time as the function declaration. Therefore, defer can access the named return value. The value returned after return is actually a defer modified value.

Defer scope

Defer in what circumstances will not be executed? A few examples are listed below:

1. When any one (master) panic occurs, it executes the defer declared before panic in the current process;

func main() {fmt.Println("...")panic(e) // defer 不会执行defer fmt.Println("defer")}

2. The os.Exit(int)  defer will no longer be executed when the active call exits the process.

func main() {fmt.Println("...")os.Exit(1) // defer 不会执行defer fmt.Println("defer")}
func main() {fmt.Println("...")defer fmt.Println("defer")os.Exit(1) // defer 不会执行}

3. In the Panic (master) process, if there is not a defer call recover() to recover, it will cause the whole process to crash after the defer declared before execution is completed;

func main() {fmt.Println("...")defer fmt.Println("defer1")defer fmt.Println("defer2")defer fmt.Println("defer3")panic("error") // defer 会执行}

4. Defer only valid for current (master) Association

package mainimport ("fmt")func main() {fmt.Println("...")go func() { panic("err") }() // defer 执行defer fmt.Println("defer1")defer fmt.Println("defer2")defer fmt.Println("defer3")}

Practical use of defer

No matter what business or program, the delay is used where the function call is executed.

Example:

Post-Update

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.