Golang defer the running time and the pits encountered

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

I. Overview of DEFER

deferis a golang unique process Control statement that delays the run time of a specified statement, runs only inside the function, and is called when the function that he belongs to is run out. For example:

1
2
3
4
 funcdefertest()  {
defer FMT. Println ("Hellodefer")
Fmt. Println ("HelloWorld")
}

It will print out first and HelloWorld then print out HelloDefer .

If there are multiple in a function defer , the order of operation and the order of the calls in the function are reversed, because they are all written in the stack:

1
2
3
4
5
Func defertest () {
Defer FMT. Println ("HelloDefer1")
Defer FMT. Println ("HelloDefer2")
Fmt. Println ("HelloWorld")
}

Operation Result:

1
2
3
Fmt. Println ("HelloDefer2")
Fmt. Println ("HelloDefer1")
Fmt. Println ("HelloWorld")

Second, defer and return

In a return function that contains statements, defer the run order is return after, but the defer code fragment that is running takes effect:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
  func main(){
FMT. Println (Deferreturn)
}
func deferreturn() int{
I: = 1
defer func(){
FMT. Println ("Defer")
i + = 1
}()
return func()int{
FMT. Println ("Return")
return i
}()
}

Operation Result:

1
2
3
Return
Defer
1

It's obvious that it's going to defer return run after that! But one problem is that defer in executing the statement i +=1 , the value returned by this logic i should be 2 instead 1 . This problem is return caused by the operating mechanism: return when an object is returned, if the return type is not a pointer or a reference type, then the return object returned will not be a copy of the objects themselves.

We can verify this view:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  func main(){
...
FMT. PRINTLN ("main:", X, &x)
}
func deferreturn() int{
...
defer ... {
FMT. Println ("Defer:", I, &i)
...
}()
return ... {
FMT. Println ("Return:", I, &i)
...
}()
}

The output of the program is:

1
2
3
Return:     10xc042008238
Defer: 10xc042008238
Main: 1 0xc042008230 the address of I in the //main function is not the same as the address of I in Deferreturn ()

If you change the return value of a function to a pointer type, the return value in the main function is consistent with the body of the function:

 1  
2
3
4
5
6
7
8
9
10
11
12
13
Span class= ' line ' >14
15
16
Func Main () {
x: = Deferreturn ()
Fmt. Println ("Main: ", X, *x)
}
Func Deferreturn () *int{
I: = 1
P: = &i
Defer func () {
*p + = 1
Fmt. Println ("Defer: ", p, *p)
}()
return func () *int{
Fmt. Println ("Return: ", p, *p)
Return P
}()
}

Results:

1
2
3
Return:     0xc0420361d1
defer: 0xc0420361d2
Main: 0xc0420361d2

Iii. Defer and panic

panicWill defer spread the panic to other functions after it has run out:

1
2
3
4
Func Deferpanic () {
Defer FMT. Println ("Hellodefer")
Panic ("Hey, I" M Panic ")
}

Results:

1
2
3
4
5
6
7
Hellodefer  //will output the code of the defer section first
Panic:hey, I "M panic
Goroutine 1 [Running]:
Main.defertest ()
E:/code/golang/src/test_src/defer/main.go:12 +0XFC
Main.main ()
E:/code/golang/src/test_src/defer/main.go:6 +0x27

Iv. defer and for loops

Do not defer use external variables inside, which can cause some unexpected errors:

1
2
3
4
5
6
7
Func defertest () {
For I: = 0; I < 5; I ++{
Defer func () {
Fmt. Printf ("%d", i)
}()
}
}

The result of its output is 55555 that the principle is simple, because defer will be called after the for loop finishes running, and the For loop I will have a value of 5, so the I value printed is 55555 .

However, if the delay function within the loop is passed in, the parameter is evaluated at the time the current defer statement executes:

 1  
2
3
4
5
6
7
 funcdefertest()  {
for 0 5; I ++{
defer funcint) {
Fmt. Printf ("%d", i)
} (i)
}
}

This will print out 43210 instead 55555 of.

Related Article

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.