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
Barbara StreisandOriginal
2024-11-19 01:12:02342Durchsuche

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
}

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
}

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
}

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
}

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!

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