指针 (GoLang)

这是一个菜鸟问题,请多多包涵。所以问题是为什么 f() 函数指向不同的地址。我的理解是变量 v 必须覆盖旧值。


package main

import "fmt"


var p = f()


func f() *int {

    v := 1

    return &v

}


func main() {

    fmt.Println(f())

    fmt.Println(f())

    fmt.Println(f())

    fmt.Println(p)

}


//0xc0000140b0

//0xc0000140b8

//0xc0000140e0

//0xc000014098


叮当猫咪
浏览 115回答 2
2回答

catspeake

编译器检测到v escapes该函数f,因此将其分配在堆上。每次调用f都会返回 的新实例v,这就是每次调用都会看到不同地址的原因。

翻过高山走不出你

给这个简单的答案Go 查找比当前堆栈帧寿命更长的变量,然后堆分配它们基本上,变量 v 转义了函数 f 堆栈帧并在堆中分配,这就是为什么您每次都会看到不同的地址打印的原因。阅读这篇关于逃逸分析的精彩介绍。https://medium.com/a-journey-with-go/go-introduction-to-the-escape-analysis-f7610174e890尝试运行逃逸分析以查看所有逃逸的变量。go build -gcflags="-m" main.go:./main.go:7:2: moved to heap: v   //points to v := 1./main.go:12:15: moved to heap: v //points to fmt.Println(f())./main.go:13:15: moved to heap: v //points to fmt.Println(f())./main.go:14:15: moved to heap: v //points to fmt.Println(f())请注意,最后一条fmt.Println(f())语句不考虑转义,因为传递给 Println 的值p是全局变量,因此它已经在堆中,因此不需要escape.
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go