Heim > Backend-Entwicklung > Golang > Warum kann ich einen einfachen Typwert nicht über eine Zeigerempfängermethode in Go ändern?

Warum kann ich einen einfachen Typwert nicht über eine Zeigerempfängermethode in Go ändern?

Barbara Streisand
Freigeben: 2024-11-19 01:12:02
Original
341 Leute haben es durchsucht

Why Can't I Modify a Simple Type Value Through a Pointer Receiver Method in Go?

Ändern einfacher Typwerte durch Zeigerempfängermethoden in Go

In Go können wir benutzerdefinierte Typen basierend auf Basistypen erstellen und deren Funktionalität erweitern durch Zeigerempfängermethoden. Beim Versuch, den Wert eines einfachen Typs über eine Zeigerempfängermethode zu ändern, stellt sich jedoch häufig die Frage.

Betrachten Sie das folgende Beispiel:

package main

import (
    "fmt"
    "strconv"
)

type FooInt int

func (fi *FooInt) FromString(i string) {
    num, _ := strconv.Atoi(i)
    tmp := FooInt(num)
    fi = &tmp // Attempt to modify the pointer
}

func main() {
    var fi *FooInt
    fi.FromString("5")
    fmt.Printf("%v\n", fi) // Prints <nil>, not the expected 5
}
Nach dem Login kopieren

Warum funktioniert der Zeiger? in main() deklariert seinen Wert nicht in die Adresse von tmp ändern?

Erklärung

Wenn Sie eine Funktion oder Methode in Go aufrufen, werden alle Argumente, einschließlich des Empfängers, angezeigt , werden als Kopien weitergegeben. Dies bedeutet, dass Sie den ursprünglichen Zeigerwert nicht innerhalb der Funktion/Methode ändern können.

Im obigen Beispiel ist fi in der FromString-Methode eine Kopie des in main() deklarierten Zeigers. Wenn Sie fi der Adresse von tmp zuweisen, ändern Sie nur den Wert der Kopie. Der ursprüngliche Zeiger bleibt unverändert.

Lösungen

Es gibt drei gängige Lösungen für dieses Problem:

1. Einen Zeiger zurückgeben:

func (fi *FooInt) FromString(i string) *FooInt {
    num, _ := strconv.Atoi(i)
    tmp := FooInt(num)
    return &tmp
}

func main() {
    var fi *FooInt
    fi = fi.FromString("5")
    fmt.Printf("%v %v\n", fi, *fi) // Prints 0xc0000b4020 5
}
Nach dem Login kopieren

2. Übergabe eines Zeigerarguments:

func (fi *FooInt) FromString(i string, p **FooInt) {
    num, _ := strconv.Atoi(i)
    tmp := FooInt(num)
    *p = &tmp
}

func main() {
    var fi *FooInt
    fi = new(FooInt) // Ensure non-nil receiver
    fi.FromString("5", &fi)
    fmt.Printf("%v %v\n", fi, *fi) // Prints 0xc0000b4020 5
}
Nach dem Login kopieren

3. Sicherstellen, dass der Empfänger nicht Null ist:

func (fi *FooInt) FromString(i string) {
    num, _ := strconv.Atoi(i)
    *fi = FooInt(num)
}

func main() {
    var fi *FooInt
    fi = new(FooInt) // Ensure non-nil receiver
    fi.FromString("5")
    fmt.Printf("%v %v\n", fi, *fi) // Prints 0xc0000b4020 5
}
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonWarum kann ich einen einfachen Typwert nicht über eine Zeigerempfängermethode in Go ändern?. 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