本文详解go函数返回指针时为何`&i`打印结果不一致——关键在于混淆了“指针变量自身的地址”与“指针所指向的地址”,通过对比c语言行为,厘清go内存模型中的指针语义。
在Go中,当你从函数返回一个指针(如 *int),实际返回的是指向堆(或逃逸分析后分配位置)上某个整数的内存地址值。但初学者常犯的一个典型错误,是误将“接收该指针的变量的地址”(即 &i)当作“指针所指向的目标地址”来打印和比较。
回顾你的代码:
func createPointerToInt() *int {
i := new(int) // 分配一个int,返回指向它的指针(例如:0x1040a128)
fmt.Println(&i) // ❌ 打印的是局部变量 i(指针类型)自身的地址,不是它指向的地址!
return i
}
func main() {
i := createPointerToInt() // i 是 *int 类型,其值为 0x1040a128
fmt.Println(&i) // ❌ 再次打印 main 中变量 i 自身的地址(如 0x1040a120)→ 两个栈变量地址不同,差8字节属正常(64位系统下指针占8字节,相邻栈变量偏移合理)
}⚠️ 关键点解析:
✅ 正确做法:要验证指针是否成功传递目标地址,应直接打印指针变量本身(即地址值),而非其地址:
func createPointerToInt() *int {
i := new(int)
*i = 42
fmt.Printf("Inside: pointer value = %p, pointed value = %d\n", i, *i)
return i
}
func main() {
p := createPointerToInt()
fmt.Printf("Outside: pointer value = %p, pointed value = %d\n", p, *p)
// 输出示例:
// Inside: pointer value = 0xc000014090, pointed value = 42
// Outside: pointer value = 0xc000014090, pointed value = 42 ← 地址值一致!
}? 补充说明:

总结:Go指针的“值”就是内存地址,函数返回指针的本质是返回一个地址数值;而 &variable 永远表示“该变量在当前作用域中的存储位置”,二者层级不同,切勿混用。