Zeigerempfänger verstehen und Instanzen kopieren
In Go kann eine Methode entweder mit einem Wertempfänger oder einem Zeigerempfänger definiert werden. Wenn alle Methoden eines Typs T einen Empfängertyp von T selbst haben, ist es sicher, Instanzen dieses Typs zu kopieren, da der Aufruf einer seiner Methoden zwangsläufig eine Kopie erstellt.
Die Situation ändert sich jedoch, wenn ein Typ verfügt über Methoden mit einem Zeigerempfänger. In diesem Fall sollte das Kopieren von Instanzen dieses Typs vermieden werden, da dadurch interne Invarianten verletzt werden können.
Das Problem beim Kopieren von Zeigern
Betrachten wir ein Beispiel zur Veranschaulichung Ausgabe. Angenommen, wir haben einen Typ Wrapper mit zwei Feldern: einem Wert v und einem Zeiger p. Wir beabsichtigen, die gleiche Zahl sowohl in v als auch im Spitzenwert von p zu speichern. Um dies sicherzustellen, stellen wir eine Set-Methode mit einem Zeigerempfänger bereit:
<code class="go">type Wrapper struct { v int p *int } func (w *Wrapper) Set(v int) { w.v = v *w.p = v }</code>
Wenn wir eine Instanz von Wrapper haben und die Set-Methode aufrufen, ändert sie den Zeigerwert von p. Wenn wir jedoch eine Kopie der Instanz erstellen, hat die Kopie denselben Zeigerwert p wie die Originalinstanz. Das bedeutet, dass sich alle nachfolgenden Methodenaufrufe auf einer der beiden Instanzen auf beide Kopien auswirken.
Beispiel:
<code class="go">a := Wrapper{v: 0, p: new(int)} b := a fmt.Printf("a.v=%d, a.p=%d; b.v=%d, b.p=%d\n", a.v, *a.p, b.v, *b.p) a.Set(1) fmt.Printf("a.v=%d, a.p=%d; b.v=%d, b.p=%d\n", a.v, *a.p, b.v, *b.p)</code>
Ausgabe:
a.v=0, a.p=0; b.v=0, b.p=0 a.v=1, a.p=1; b.v=0, b.p=1
In In diesem Beispiel wird der Wert von b ungültig, nachdem a.Set(1) aufgerufen wurde, da b.v nicht gleich *b.p ist. Dies liegt daran, dass der Zeiger p in a und b auf denselben zugrunde liegenden Wert zeigt.
Um solche Probleme zu vermeiden, wird empfohlen, bei der Verwendung von Methoden mit Zeigerempfängern mit Zeigerwerten zu arbeiten. Wenn der Typ alternativ nur Wertempfänger haben kann, ist es sicher, Instanzen dieses Typs unabhängig von Methodenaufrufen zu kopieren.
Das obige ist der detaillierte Inhalt von## Warum kann ich in Go nicht einfach Instanzen von Typen mit Zeigerempfängern kopieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!