为什么当我们使用(*structObj)引用struct时,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

Go playground

推荐答案

当你写的时候

obj := *p

您正在复制由p(*个解引用p)指向的struct的值.它类似于:

var obj me = *p

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

请注意,objIF属于类型me,而p属于类型*me.但它们是不同的价值.更改字段obj的值不会影响p中该字段的值(除非me struct 中具有作为字段的引用类型,即切片、映射或通道.请参见herehere.)如果要实现该效果,请使用:

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

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

Go相关问答推荐

"k8s.io/apimachinery/pkg/runtime.对象(缺少方法DeepCopyBody)

杜松子wine -戈尼克背景在 children 围棋例行公事中被取消

Go Net/http路由

Go PQ驱动程序无法使用默认架构进行查询

如何描述OpenAPI规范中围棋的数据类型.JSON?

Golang文本/模板序列范围

GORM:一个表的两个外键

Exchange Web 服务 - 使用 soap xml 请求查找所有未读邮件

缺少签名帮助文档

动态 SQL 集 Golang

如何在 Docker 容器中使用私有存储库进行身份验证

速率限制特定端点

如何将一片十六进制字节转换为整数

此代码如何生成内存对齐切片?

使用 Golang SQL 驱动程序连接到snowflake

Golang 使用 docker 将敏感数据作为参数传递

Go Fyne 禁用 HSplit 调整大小?

为什么 Go 中的 maps.Keys() 将 map 类型指定为 M?

如何断言类型是指向golang中接口的指针

在 etcd 键值存储中禁用历史记录