传递指向go defer函数的指针不起作用[重复]

nr7wwzry  于 2023-03-06  发布在  Go
关注(0)|答案(1)|浏览(228)
    • 此问题在此处已有答案**:

Go - Inconsistent Evaluation of Deferred Functions(3个答案)
The deferred call's arguments are evaluated immediately(4个答案)
When defer func evaluates its parameters(3个答案)
Go defer does not behave as expected when Unmount(2个答案)
golang defer not evaluating when expected(2个答案)
8小时前关门了。
在我的代码中,我尝试使用numAddr来记录defer语句之后num的更改

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

func main() {
    deferRun()
}

但是我得到的是num is 1而不是2,为什么defer函数使用值而不是*numAddr的地址?
那我就试试别的办法

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()
}

这一次它工作了,我得到了num is 2,所以我想也许defer fmt.Printf(something)在声明字符串时立即存储了它,并且在defer函数实际运行时没有使用numAddr?

yyyllmsg

yyyllmsg1#

有趣的问题。要回答这个问题,你必须知道一条规则,就像这个围棋教程https://go.dev/tour/flowcontrol/12
The deferred call's arguments are evaluated immediately, but the function call is not executed until the surrounding function returns..

    • 示例1:**告诉defer函数打印位于指定内存地址的值。
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  
}

输出将为2。

    • 示例2:**告诉defer函数打印指定的值。
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  
}

输出将为1。

相关问题