gpt4 book ai didi

pointers - 为什么所有嵌套的结构对象在打印出来时都具有相同的地址?

转载 作者:IT王子 更新时间:2023-10-29 01:54:19 27 4
gpt4 key购买 nike

我试图在 a := b 中找出 a 是否是结构的不同副本,例如 func pass_by_value(a some_struct)

但是我发现我不理解打印语句。

考虑这个 go playground

    nested_level2 := test_assign_nested_level2{}
nested_level1 := test_assign_nested{nested_level2}
top_level := test_assign{nested_level1}

assign := top_level
fmt.Println("top_level address")
fmt.Printf("%p", &top_level)
fmt.Println(" ")
fmt.Println("1 level address")
fmt.Printf("%p", &top_level.Level1)
fmt.Println(" ")
fmt.Println("2 level address")
fmt.Printf("%p", &top_level.Level1.Level_2)
fmt.Println("------------------------")

fmt.Println("assign top_level address")
fmt.Printf("%p", &assign)
fmt.Println(" ")
fmt.Println("1 level address")
fmt.Printf("%p", &assign.Level1)
fmt.Println(" ")
fmt.Println("2 level address")
fmt.Printf("%p", &assign.Level1.Level_2)

上面的输出是

top_level address
0x10410020
1 level address
0x10410020
2 level address
0x10410020
assign top_level address
0x10410024
1 level address
0x10410024
2 level address
0x10410024

我希望输出类似于

    fmt.Println("top_level address")
fmt.Printf("%p", &top_level)
fmt.Println(" ")
fmt.Println("1 level address")
fmt.Printf("%p", &nested_level1)
fmt.Println(" ")
fmt.Println("2 level address")
fmt.Printf("%p", &nested_level2)
fmt.Println(" ")
fmt.Println(" ------------------------------- ")

在哪里

top_level address
0x421152280
1 level address
0x421152270
2 level address
0x421152260

每个结构都有不同的地址。但看起来子结构与父结构具有相同的地址。

为什么结构中的所有嵌套元素都具有相同的地址?

:= 实际上递归地复制了一个新的struct 吗?就像打印语句所示? (即 := 将返回一个全新的结构副本,其每个字段内容也是递归的一个全新副本)

最佳答案

Go 中的类型不是其他事物的自动包装器,而只是两件事:类型允许附加方法,类型提供内存中的布局。对于这里的问题,将方法附加到类型的能力是无关紧要的。让我们看一下问题的中性表述:

type A int64
type B { a A }
type C { b B }

这声明了三种具有以下内存布局的类型:

  • 类型 A 的内存布局为 int64(即 8 个字节)。
  • 类型 B 具有单个 A 的内存布局,即 int64,因此 8 个字节。
  • 类型 C 具有单个 B 的内存布局,即单个 A,即 int64,因此 8 个字节。

关于内存布局的类型 B 不是 A 的“包装器”,至少包装器绝对没有添加任何内容。从纯内存布局的角度来看,定义类型 B 是无用的(但它允许将不同的方法附加到 B 而不是附加到 A)。

现在应该清楚 a​​ c C 的地址是其 8 个字节中第一个字节的地址,这与 c.b 的地址相同,c.b.a 的地址相同。对 C 的任何赋值都只是一个机器字的副本(在 64 位架构上)。

如果定义 type D { a A; b B } 它变得更有趣,因为 D 现在有 16 个字节长。 (向 D 添加更多内容甚至可能由于填充而留下空洞。)但是 D 仍然没有向内存中彼此相邻的 A 和 B 提供任何内容(期望新方法集)。

关于pointers - 为什么所有嵌套的结构对象在打印出来时都具有相同的地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46313250/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com