是dereference golang struct返回struct的新副本?

ken*_*ken 11 struct pointers go dereference

为什么当我们使用(*structObj)引用struct时,golang似乎返回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)
}
Run Code Online (Sandbox Code Playgroud)

产量

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
Run Code Online (Sandbox Code Playgroud)

golang游乐场

Jim*_*imB 14

不,"赋值"总是在Go中创建一个副本,包括赋值给函数和方法参数.该语句obj := *p复制*pto 的值obj.

如果将语句更改p.color = "purple"(*p).color = "purple"您将获得相同的输出,因为解除引用p本身不会创建副本.

  • `引用p本身不会创建副本`这澄清了我的困惑,谢谢 (2认同)

abh*_*ink 9

当你写作

obj := *p
Run Code Online (Sandbox Code Playgroud)

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

var obj me = *p
Run Code Online (Sandbox Code Playgroud)

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

请注意,obj如果是类型me,则p是类型*me.但它们是不同的价值观.改变的字段的值obj将不会影响该字段的值中p(除非me结构具有作为场,即切片,地图或通道在它的一个引用类型.参见这里在这里).如果你想带来这种效果,请使用:

obj := p
// equivalent to: var obj *me = p
Run Code Online (Sandbox Code Playgroud)

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

  • @ken:我不明白你的意思。您需要某种值,因此它要么是结构值,要么是指针值。如果您想引用相同的结构或避免复制,请使用指针。 (2认同)

Mic*_*ner 6

tl;dr*在 Go 中解引用(使用运算符)不会复制。它返回指针指向的值。