Pointer- vs. Value-Receiver
Teil des Abschnitts Objektorientierte Programmierung der GO-Journey von Coddy — Lektion 8 von 107.
Methoden können entweder einen Wert-Empfänger oder einen Zeiger-Empfänger haben. Ein Wert-Empfänger arbeitet mit einer Kopie des Structs. Ein Zeiger-Empfänger arbeitet mit dem ursprünglichen Struct und kann dessen Felder ändern.
Value-Receiver — arbeitet auf einer Kopie
type Counter struct {
Count int
}
func (c Counter) GetCount() int {
return c.Count
}
// Dies verändert das Original NICHT
func (c Counter) IncrementWrong() {
c.Count++ // Ändert nur die Kopie!
}Pointer-Receiver — verändert das Original
// Dies verändert das Original
func (c *Counter) Increment() {
c.Count++
}
func (c *Counter) Reset() {
c.Count = 0
}Beides zusammen verwenden
func main() {
counter := Counter{Count: 0}
counter.Increment()
counter.Increment()
fmt.Println(counter.GetCount()) // Ausgabe: 2
counter.Reset()
fmt.Println(counter.GetCount()) // Ausgabe: 0
}Verwenden Sie einen Value-Receiver, wenn die Methode nur Daten liest. Verwenden Sie einen Pointer-Receiver (*StructName), wenn die Methode die Felder des Structs ändern muss. Go übernimmt die Referenzierung automatisch – Sie rufen beide auf die gleiche Weise auf.
Aufgabe
MittelFügen Sie dem Wallet-Struct Methoden unter Verwendung der korrekten Receiver-Typen hinzu:
GetBalance— Value-Receiver, gibt den aktuellen Kontostand zurückDeposit— Pointer-Receiver, fügt den Betrag zum Kontostand hinzuWithdraw— Pointer-Receiver, zieht den Betrag nur ab, wenn ausreichend Guthaben vorhanden ist
Spickzettel
Methoden können entweder einen Value-Receiver oder einen Pointer-Receiver haben. Ein Value-Receiver arbeitet mit einer Kopie des Structs. Ein Pointer-Receiver arbeitet mit dem ursprünglichen Struct und kann dessen Felder ändern.
Value-Receiver — arbeitet mit einer Kopie:
type Counter struct {
Count int
}
func (c Counter) GetCount() int {
return c.Count
}Pointer-Receiver — modifiziert das Original:
func (c *Counter) Increment() {
c.Count++
}Verwenden Sie einen Value-Receiver, wenn die Methode nur Daten liest. Verwenden Sie einen Pointer-Receiver (*StructName), wenn die Methode die Felder des Structs ändern muss.
Probier es selbst
package main
import "fmt"
func main() {
var balance, deposit, withdraw float64
fmt.Scan(&balance, &deposit, &withdraw)
w := Wallet{Balance: balance}
fmt.Printf("Balance: %.2f\n", w.GetBalance())
w.Deposit(deposit)
fmt.Printf("After deposit: %.2f\n", w.GetBalance())
w.Withdraw(withdraw)
fmt.Printf("After withdrawal: %.2f\n", w.GetBalance())
fmt.Printf("Final balance: %.2f\n", w.GetBalance())
}Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der Go OOP
Externe DateienGo Workspace & ModulePackages & ImportsExportierte vs. nicht-exportierte NamenEinführung in OOP in GoStructs als KlassenMethoden für Structs definierenPointer- vs. Value-ReceiverStruct-InitialisierungKonstruktor-FunktionenZusammenfassung – Einfacher Taschenrechner4Interfaces
Einführung in InterfacesImplizite ImplementierungInterface als VertragLeeres Interface (any)Type AssertionType SwitchInterface-KompositionStringer & Error InterfacesRückblick - Formen-Rechner7Kapselung
Exportierte vs. nicht exportierte FelderKapselung auf Paket-EbeneGetter- & Setter-MethodenInformation Hiding in GoZusammenfassung - Studierendendatensätze10Generics (Go 1.18+)
Einführung in GenericsTypparameterType ConstraintsGenerische StructsWorkaround für generische MethodenZusammenfassung – Generische Collection2Vertiefung: Typen & Structs
Basis- & zusammengesetzte TypenBenutzerdefinierte TypdefinitionenStruct TagsAnonyme StructsVerschachtelte StructsZero Values & StandardwerteZusammenfassung - Kontaktbuch5Komposition statt Vererbung
Warum Go keine Vererbung hatGrundlagen des Struct EmbeddingMethod PromotionEinbetten mehrerer StructsEmbedding vs. AggregationShadowing eingebetteter MethodenZusammenfassung – Mitarbeiter-Hierarchie8Fehlerbehandlung & OOP
Das error-InterfaceEigene FehlertypenError Wrapping (fmt.Errorf)Sentinel-Fehlererrors.Is() und errors.As()Panic, Defer und RecoverZusammenfassung – Datei-Parser3Zeiger & Speicher
Zeiger-Grundlagen in GoZeiger auf StructsWertübergabe vs. ReferenzübergabeDie new() FunktionGarbage Collection in GoWiederholung – Linked List Builder6Polymorphismus in Go
Polymorphismus über InterfacesDuck Typing in GoInterface-ErfüllungsregelnPolymorphe CollectionsDependency InjectionZusammenfassung – Payment Processor9Nebenläufigkeit & OOP
Goroutines GrundlagenChannels & KommunikationGepufferte vs. ungepufferte ChannelsSelect-Anweisungsync.Mutex & sync.RWMutexsync.WaitGroupThread-sicheres Struct-DesignZusammenfassung - Worker Pool