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 dies interne Invarianten verletzen könnte.
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:
type Wrapper struct {
v int
p *int
}
func (w *Wrapper) Set(v int) {
w.v = v
*w.p = v
}
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:
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)
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 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.
Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.
Copyright© 2022 湘ICP备2022001581号-3