Heim > Backend-Entwicklung > Golang > Warum ändert meine Go-Struct-Setter-Funktion die ursprüngliche Struktur nicht?

Warum ändert meine Go-Struct-Setter-Funktion die ursprüngliche Struktur nicht?

Mary-Kate Olsen
Freigeben: 2024-12-21 10:00:17
Original
698 Leute haben es durchsucht

Why Doesn't My Go Struct Setter Function Modify the Original Struct?

Setter für Strukturtypen verstehen

In Go können Strukturen durch Setter-Funktionen geändert werden. Bei der Verwendung von Settern für Strukturtypen können jedoch bestimmte Verhaltensweisen unerwartet sein. Betrachten Sie das folgende Beispiel:

package main

import "fmt"

type T struct { Val string }

// this setter seems not to work
func (t T) SetVal(s string) {
    t.Val = s
}

// this setter, using ptr to T, seems to work ok
func (t *T) SetVal2(s string) {
    (*t).Val = s
}

func main() {
    v := T{"abc"}
    fmt.Println(v)        // prints {abc}
    v.SetVal("pdq")
    fmt.Println(v)        // prints {abc}, was expecting {pdq}!
    v.SetVal2("xyz")
    fmt.Println(v)        // prints {xyz}!
}
Nach dem Login kopieren

Es stellt sich die Frage: Warum ändert die SetVal-Funktion die ursprüngliche Struktur nicht wie erwartet?

Werte-Semantik verstehen

Der Hauptunterschied liegt darin, wie Strukturen an Funktionen übergeben werden. Wenn eine Struktur als Wert übergeben wird (wie in SetVal), wird eine Kopie der Struktur innerhalb der Funktion erstellt. Alle innerhalb der Funktion vorgenommenen Änderungen wirken sich nur auf diese temporäre Kopie aus und lassen die ursprüngliche Struktur unverändert.

Bei der Übergabe einer Struktur per Zeiger (wie in SetVal2) erhält die Funktion jedoch Zugriff auf die ursprüngliche Struktur im Speicher. Alle innerhalb der Funktion vorgenommenen Änderungen werden direkt in der ursprünglichen Struktur widergespiegelt.

Wertnachweissemantik

Dies kann durch Drucken der Speicheradressen der beteiligten Strukturen veranschaulicht werden :

package main

import "fmt"

type T struct { Val string }

func (t T) SetVal(s string) {
    fmt.Printf("Address of copy is %p\n", &t)
}

func (t *T) SetVal2(s string) {
    fmt.Printf("Pointer argument is %p\n", t)
}

func main() {
    v := T{"abc"}
    fmt.Printf("Address of v is %p\n", &v)
    v.SetVal("pdq")
    v.SetVal2("xyz")
}
Nach dem Login kopieren

Dieser Code erzeugt eine Ausgabe, die der folgenden ähnelt:

Address of v is 0xf840001290
Address of copy is 0xf8400013e0
Pointer argument is 0xf840001290
Nach dem Login kopieren

Beachten Sie, dass der erste und dritte gedruckte Adressen sind gleich, was darauf hinweist, dass sie sich auf dieselbe Struktur beziehen. Die zweite Adresse ist jedoch anders und stellt die in SetVal erstellte temporäre Kopie dar.

Das obige ist der detaillierte Inhalt vonWarum ändert meine Go-Struct-Setter-Funktion die ursprüngliche Struktur nicht?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
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
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage