Heim  >  Artikel  >  Backend-Entwicklung  >  ## Warum kann ich in Go nicht einfach Instanzen von Typen mit Zeigerempfängern kopieren?

## Warum kann ich in Go nicht einfach Instanzen von Typen mit Zeigerempfängern kopieren?

Linda Hamilton
Linda HamiltonOriginal
2024-10-25 05:03:02171Durchsuche

## Why Can't I Just Copy Instances of Types With Pointer Receivers in Go?

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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn