N-1-萘乙基二胺盐酸盐 2024-06-20 15:31 采纳率: 50%
浏览 9
已结题

回答go语言空结构体的地址问题

Code:

func main(){
    var (
        a struct{}
        b struct{}
    )
    println("&a:", &a)
    println("&b:", &b)
    println("&a == &b:", &a == &b)
    m := &a
    n := &b
    println("m == n:", m == n)

    x := make([]struct{}, 10)
    println("&x[0] == &x[1]:", &x[0] == &x[1])
}

Result:

PS D:\emptyStruct> go run -gcflags '-m -N -l' main.go  
./main.go:15:11: make([]struct {}, 10) does not escape
&a: 0xc00004ff05  
&b: 0xc00004ff05  
&a == &b: false  
m == n: true  
&x[0] == &x[1]: true  

为什么a和b的地址都是一样的,但是&a == &b却为false,但是将地址赋值给变量m == n就为true,谁能解释一下为什么?

  • 写回答

1条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-06-20 15:31
    关注

    引自免费微信小程序:皆我百晓生

    这个问题涉及到 Go 语言中内存分配的一些特性。让我们一步一步地解析这个问题。

    首先,理解什么是地址。在 Go 语言中,变量在内存中都有一个地址,这是变量在内存中的位置。当我们取一个变量的地址时(使用 & 操作符),我们得到的就是这个变量在内存中的地址。

    关于你的代码:

    var (
        a struct{}
        b struct{}
    )
    

    在这个例子中,ab 是两个独立的空结构体变量。虽然它们都是空结构体,但它们是不同的变量,因此它们应该有不同的内存地址。这就是为什么 &a == &b 返回 false 的原因。尽管 ab 可能在内存中相邻,但它们是不同的变量,因此它们的地址是不同的。

    接下来看:

    println("m == n:", m == n)
    

    这里你创建了两个指针变量 mn,分别指向 ab 的地址。由于 ab 都是存储在栈上的(因为它们是在函数内部定义的局部变量),它们的地址实际上是相同的(至少在大多数现代计算机架构上)。因此,当你比较这两个指针变量时(即比较它们所指向的地址),结果是 true。这是因为指针变量本身并不存储它们指向的对象的值,只是存储了对象的地址。在这个特定的例子中,即使 ab 是不同的变量,它们的地址(即指针值)是相同的,因为它们在内存中相邻并且是局部变量。这通常是由于 Go 语言优化栈上相邻变量的存储方式导致的。但是请注意,这并不意味着这两个变量的内容相同,它们是不同的变量实例。这是 Go 语言的一种特性,并不保证在所有情况下都会如此。在其他情况下,不同的变量可能会有不同的地址。因此,虽然在这个特定情况下 m == n 返回 true,但这并不总是如此。对于其他类型的变量或更复杂的情况,可能会有不同的结果。因此,在比较指针值时应该小心谨慎。至于最后一个部分:为什么 &x[0] == &x[1] 返回 true 是因为你声明了一个含有多个 struct 的切片并存储在连续的内存空间中,所以它们的地址是相同的。希望这个解释能帮助你理解这个问题!

    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 6月21日
  • 创建了问题 6月20日