Home  >  Article  >  Backend Development  >  Passing pointer to go defer function doesn't work

Passing pointer to go defer function doesn't work

WBOY
WBOYforward
2024-02-13 12:24:09609browse

将指针传递给 go defer 函数不起作用

In PHP programming, the pointer may not work when passed to the go defer function. Pointers in PHP are used to store the memory address of variables. By passing the pointer, the value of the original variable can be modified inside the function. However, when passing a pointer to a go defer function, it sometimes happens that the original variable cannot be modified. This may be because the go defer function creates a new Goroutine when executed, and the pointer may point to a different memory space, resulting in the failure to modify the value of the variable correctly. Therefore, in PHP programming, pointers should be passed to go defer functions with caution to avoid unexpected problems.

Question content

In my code, I try to use numaddr to record the changes in num after the defer statement

func deferrun() {
    num := 1
    numaddr := &num
    defer fmt.printf("num is %d", *numaddr)
    num = 2
    return
}

func main() {
    deferrun()
}

But I get num is 1 instead of 2, why does the defer function use the value of *numaddr instead of the address?

Then let me try another method

func deferRun() {
    num := 1
    numAddr := &num
    defer func(intAddr *int){
        fmt.Printf("num is %d", *numAddr)
    }(numAddr)
    
    num = 2
    fmt.Println("num is", *numAddr)
    return
}

func main() {
    deferRun()
}

This time it worked, I got num was 2, so I thought maybe defer fmt.printf(something) stored the string immediately when declaring it, and Isn't numaddr used when the defer function actually runs?

Solution

Interesting question. To answer this question, you must know a rule, like this go tutorial https://go.dev/tour/flowcontrol/12

The parameters of a delayed call are evaluated immediately, but the function call is not executed until the surrounding function returns. .

Example 1: Tell the defer function to print the value located at the specified memory address.

func deferrun() {
    num := 1
    numaddr := &num //address of variable num in stack memory, 0xc000076f38 for example
    defer func(intaddr *int){
        fmt.printf("num is %d", *numaddr)
    }(numaddr) //hey go, when the surrounding function returns, print the value located in this address (numaddr=0xc000076f38)
    num = 2 //now the value located in address 0xc000076f38 is 2
    return  
}

The output will be 2.

Example 2: Tell the defer function to print the specified value.

func deferRun() {
    num := 1
    numAddr := &num //address of variable num in stack memory, 0xc000076f38 for example
    defer fmt.Printf("num is %d", *numAddr) //Hey Go, when the surrounding function returns, print the this value *numAddr (*numAddr is 1 for now)
    num = 2 //Now the value located in address 0xc000076f38 is 2 but you told the defer function to print 1 before
    return  
}

The output will be 1.

The above is the detailed content of Passing pointer to go defer function doesn't work. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete