Heim >Backend-Entwicklung >Golang >Warum erfordert die Verwendung von Zeigerempfängern in Go-Schnittstellenimplementierungen die Rückgabe von Zeigern?

Warum erfordert die Verwendung von Zeigerempfängern in Go-Schnittstellenimplementierungen die Rückgabe von Zeigern?

DDD
DDDOriginal
2024-12-12 11:35:11739Durchsuche

Why Does Using Pointer Receivers in Go Interface Implementations Require Returning Pointers?

Zeigerempfänger in Golang und Schnittstellenimplementierung

In Go ermöglichen Empfängerfunktionen Methoden, mit bestimmten Typen zu arbeiten. Wenn eine Methode über einen Zeigerempfänger verfügt, kann sie die tatsächliche Instanz der Struktur ändern.

Das Problem verstehen

Bedenken Sie den folgenden Codeausschnitt:

type IFace interface {
    SetSomeField(newValue string)
    GetSomeField() string
}

type Implementation struct {
    someField string
}

// Method with non-pointer receiver
func (i Implementation) GetSomeField() string {
    return i.someField
}

// Method with non-pointer receiver
func (i Implementation) SetSomeField(newValue string) {
    i.someField = newValue
}

In diesem Code haben beide Methoden Nicht-Zeiger-Empfänger. Das bedeutet, dass beim Aufruf von SetSomeField eine Kopie der Struktur erstellt und diese Kopie geändert wird. Die ursprüngliche Instanz bleibt unverändert.

Verwendung eines Zeigerempfängers

Um die tatsächliche Instanz zu ändern, sollte die SetSomeField-Methode einen Zeigerempfänger haben:

// Method with pointer receiver
func (i *Implementation) SetSomeField(newValue string) {
    i.someField = newValue
}

Jetzt kann SetSomeField die ursprüngliche Instanz ändern. Dies wirft jedoch ein Problem bei der Implementierung der IFace-Schnittstelle auf:

package main

import (
    "fmt"
)

type IFace interface {
    SetSomeField(newValue string)
    GetSomeField() string
}

type Implementation struct {
    someField string
}

// Method with pointer receiver
func (i *Implementation) GetSomeField() string {
    return i.someField
}

// Method with pointer receiver
func (i *Implementation) SetSomeField(newValue string) {
    i.someField = newValue
}

func Create() IFace {
    obj := Implementation{someField: "Hello"}
    return obj // Offending line
}

func main() {
    a := Create() // Assigning an Implementation value to an IFace variable
    a.SetSomeField("World") // Will panic because a is an Implementation value, not a pointer
    fmt.Println(a.GetSomeField())
}

Das Kompilieren dieses Codes führt zu einer Panik, da Create einen Implementierungswert und keinen Zeiger darauf zurückgibt. Um die Schnittstelle mit einem Zeigerempfänger zu implementieren, muss die Methode als Zeigerempfänger deklariert werden und die Create-Funktion muss einen Zeiger auf die Implementierung zurückgeben.

type IFace interface {
    SetSomeField(newValue string)
    GetSomeField() string
}

type Implementation struct {
    someField string
}

// Method with pointer receiver
func (i *Implementation) GetSomeField() string {
    return i.someField
}

// Method with pointer receiver
func (i *Implementation) SetSomeField(newValue string) {
    i.someField = newValue
}

func Create() *Implementation {
    obj := Implementation{someField: "Hello"}
    return &obj
}

func main() {
    var a IFace
    a = Create() // Now assigning a pointer to Implementation to an IFace variable
    a.SetSomeField("World")
    fmt.Println(a.GetSomeField())
}

Jetzt ist a ein Zeiger auf einen Implementierungswert, der implementiert IFace mit Zeigerempfängern. Über SetSomeField vorgenommene Änderungen wirken sich auf die ursprüngliche Instanz aus.

Das obige ist der detaillierte Inhalt vonWarum erfordert die Verwendung von Zeigerempfängern in Go-Schnittstellenimplementierungen die Rückgabe von Zeigern?. 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