Heim > Backend-Entwicklung > Golang > Warum funktioniert das Ändern eines einfachen Typs über eine Zeigerempfängermethode in Go nicht wie erwartet?

Warum funktioniert das Ändern eines einfachen Typs über eine Zeigerempfängermethode in Go nicht wie erwartet?

Patricia Arquette
Freigeben: 2024-11-16 12:29:03
Original
233 Leute haben es durchsucht

Why Does Modifying a Simple Type Through a Pointer Receiver Method in Go Not Work as Expected?

So ändern Sie Werte einfacher Typen durch Zeigerempfängermethoden in Go

Wenn Sie mit benutzerdefinierten Typen arbeiten, die auf Basistypen basieren, möchten Sie möglicherweise um ihre Werte mithilfe von Zeigerempfängerfunktionen zu ändern. Wenn Sie dies jedoch versuchen, kann es vorkommen, dass die Änderungen scheinbar unwirksam sind. Hier ist eine detaillierte Erklärung:

Das Problem

Bedenken Sie den folgenden Code:

package main

import "fmt"

type FooInt int

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

func main() {
    var fi *FooInt
    fi.FromString("5")
    fmt.Println(fi) // Prints nil
}
Nach dem Login kopieren

Wenn Sie dieses Programm ausführen, werden Sie das bemerken Der Wert von fi bleibt trotz des Versuchs der FromString-Methode, ihn zu ändern, Null.

Erklärung

In Go werden alle Funktionsargumente – einschließlich des Empfängers – als Wert übergeben. Das bedeutet, dass innerhalb der FromString-Methode der fi-Zeiger eine Kopie des tatsächlichen Zeigers ist, der in main deklariert ist. Wenn Sie fi innerhalb der Methode ändern, ändern Sie nur die Kopie, nicht den ursprünglichen Zeiger.

Um dieses Problem zu beheben, haben Sie zwei Möglichkeiten:

1. Geben Sie den geänderten Zeiger zurück

Sie können den geänderten Zeiger von der FromString-Methode zurückgeben und ihn wieder dem ursprünglichen Zeiger zuweisen:

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.Println(fi) // Prints the address of the modified pointer
}
Nach dem Login kopieren

2. Stellen Sie sicher, dass der Empfänger nicht Null ist.

Alternativ können Sie sicherstellen, dass der Empfänger nicht Null ist, bevor Sie versuchen, den angezeigten Wert zu ändern:

func (fi *FooInt) FromString(i string) {
    if fi == nil {
        fi = new(FooInt) // Initialize fi if it's nil
    }
    num, _ := strconv.Atoi(i)
    *fi = FooInt(num)
}

func main() {
    var fi *FooInt
    fi.FromString("5")
    fmt.Println(fi) // Prints the address of the modified pointer
}
Nach dem Login kopieren

Dadurch wird sichergestellt, dass der Empfänger Null ist initialisiert und der Zeigerwert kann direkt geändert werden.

Zusammenfassend gilt: Wenn Sie Werte über Zeigerempfängermethoden in Go ändern, denken Sie daran, dass der Empfänger eine Kopie ist und Sie entweder den geänderten Zeiger zurückgeben oder sicherstellen müssen, dass der Empfänger eine Kopie ist ungleich Null, um unerwartetes Verhalten zu vermeiden.

Das obige ist der detaillierte Inhalt vonWarum funktioniert das Ändern eines einfachen Typs über eine Zeigerempfängermethode in Go nicht wie erwartet?. 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