You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于Golang中Defer结合指针的代码运行结果的疑问

为什么这段Go代码的运行结果是这样?

代码示例

package main

import (
    "fmt"
)

type userinfo struct {
    id int
}

func main() {
    user := new(userinfo)
    user = nil
    fmt.Println("nil user address : ", &user)
    defer Println(user)
    if user == nil {
        user = &userinfo{
            id: 1,
        }
        fmt.Println("nil user point new user:", &user)
    }
}

func Println(user *userinfo) {
    fmt.Println("defer: ", &user)
    fmt.Println("defer:", user)
}

运行结果

nil user address :  0xc00000e028
nil user point new user: 0xc00000e028
defer:  0xc00000e038
defer: <nil>

结果解释

  • 变量user自身的地址固定不变:user是main函数的局部变量,存储在栈上,它的内存地址(&user)从声明到销毁都不会改变。不管user的值(也就是它指向的结构体指针)怎么修改,它自己的地址始终是同一个,所以前两行输出的地址完全一致。
  • defer语句的参数在声明时就完成求值:当执行defer Println(user)时,Go会立即计算出此时user的值(也就是nil)并保存,后续即使修改user的指向(给它赋值新的userinfo结构体指针),也不会影响已经保存的defer参数值。所以最后Println函数接收到的参数还是nil。
  • Println函数的形参是独立的局部变量:Println里的user是函数参数,是main中user的副本,它有自己的栈内存地址,所以&user的输出和main里的&user不一样,这就是第三行输出地址不同的原因。

内容的提问来源于stack exchange,提问作者Aa troy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 22:17:19