2016-07-18 26 views
5

Warum, wenn wir struct mit (* structObj) referenzieren, scheint golang eine neue Kopie von structObj zurückzugeben, als dieselbe Adresse von original structObj zurückzugeben? Könnte einige misunderstand von mir auf das sein, suchen Sie so freundlich Klärungist dereference golang struct eine neue Kopie von struct zurückgeben?

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) 
} 

Ausgabe

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 

golang playground

Antwort

2

Wenn Sie

obj := *p 

Sie kopieren den Wert von struct schreiben gezeigt auf (* Dereferenzierungen). Es ist ähnlich wie:

var obj me = *p 

So obj eine neue Variable vom Typ me, auf den Wert von *p initialisiert. Dies bewirkt, dass obj eine andere Speicheradresse hat.

Beachten Sie, dass obj wenn vom Typ me ist, während vom Typ *me ist. Aber sie sind getrennte Werte. Das Ändern eines Werts eines Felds von obj beeinflusst den Wert dieses Felds in p (es sei denn, die Struktur me hat einen Referenztyp als Feld, d. H. Scheibe, Karte oder Kanäle. Siehe here und here.). Wenn Sie über diesen Effekt bringen wollen, verwenden Sie:

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

Jetzt obj Punkte auf das gleiche Objekt wie p. Sie haben selbst noch unterschiedliche Adressen, enthalten aber die gleiche Adresse des eigentlichen me Objekts.

+0

gibt es eine Möglichkeit, den gleichen dereferenzierten Zeiger auf p zu bekommen? Wie im main() - func, wenn wir die Struktur als Slice anhängen, müssen wir sie immer im Append selbst dereferenzieren, d. h. res = append (res, * p). – ken

+0

Es geht nicht nur um "Erstellen" einer neuen Variablen, die Zuweisung zu einer vorhandenen Variablen über eine Dereferenzierung kopiert den Wert, z. '* a = * b' kopiert immer noch' * b' nach '* a'. – JimB

+0

@jimB yap, gibt es eine Möglichkeit, die wiederholte Kopie zu vermeiden? im Grunde muss die Operation nur mit der gleichen p struct umgehen. – ken

6

Nein, "Zuweisung" erstellt immer eine Kopie in Go, einschließlich der Zuordnung zu Funktion und Methode Argumente. Die Anweisung obj := *p kopiert den Wert *p in obj.

Wenn Sie die Anweisung p.color = "purple" zu (*p).color = "purple" ändern, erhalten Sie die gleiche Ausgabe, da die Dereferenzierung selbst keine Kopie erstellt.

+0

in der Tat, von c Hintergrund kommend, dies verwirrt mich. Danke, denke beide Antworten sind korrekt und erreiche mich ungefähr zur gleichen Zeit, also wähle mehr Details, aber verbessere das auch für deine Antwort! – ken

+0

'Dereferenzierung von p selbst erstellt keine Kopie 'dies geklärt meine Verwirrung, danke – stackoverflower