一尘不染

取消引用结构是否会返回新的结构副本?

go

为什么当我们使用struct引用结构时(*structObj),Go似乎会返回的新副本,structObj而不是返回原始的相同地址structObj?这可能是我的误解,所以我要求澄清

package main

import (
    "fmt"
)

type me struct {
    color string
    total int
}

func study() *me {
    p := me{}
    p.color = "tomato"
    fmt.Printf("%p\n", &p.color)
    return &p
}

func main() {
    p := study()
    fmt.Printf("&p.color = %p\n", &p.color)

    obj := *p
    fmt.Printf("&obj.color = %p\n", &obj.color)
    fmt.Printf("obj = %+v\n", obj)

    p.color = "purple"
    fmt.Printf("p.color = %p\n", &p.color)
    fmt.Printf("p = %+v\n", p)
    fmt.Printf("obj  = %+v\n", obj)

    obj2 := *p
    fmt.Printf("obj2 = %+v\n", obj2)
}

输出量

0x10434120
&p.color = 0x10434120
&obj.color = 0x10434140   //different than &p.color!
obj = {color:tomato total:0}
p.color = 0x10434120
p = &{color:purple total:0}
obj  = {color:tomato total:0}
obj2 = {color:purple total:0} // we get purple now when dereference again

去操场


阅读 279

收藏
2020-07-02

共1个答案

一尘不染

当你写

obj := *p

您正在复制p*dereferences p)指向的struct的值。它类似于:

var obj me = *p

所以obj是一个类型的新变量me,被初始化为的值*p。这将导致obj具有不同的内存地址。

请注意,obj如果是type me,则while p是type
*me。但是它们是不同的值。更改of字段obj的值不会影响in的字段值p(除非mestruct在其中具有引用类型作为字段,即slice,map或channel。如果要产生这种效果请使用:

obj := p
// equivalent to: var obj *me = p

现在obj指向与相同的对象p。它们本身仍然具有不同的地址,但是在它们内部拥有与实际me对象相同的地址。

2020-07-02