传递指针去延迟函数不起作用

问题描述 投票:0回答:1

在我的代码中我尝试使用

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)
在声明时立即存储了字符串,而在延迟函数实际运行时没有使用numAddr?

go deferred
1个回答
0
投票

有趣的问题。要回答这个问题,你必须知道一个规则,就像这个 Go 教程中一样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.

© www.soinside.com 2019 - 2024. All rights reserved.