Die new() Funktion
Teil des Abschnitts Objektorientierte Programmierung der GO-Journey von Coddy — Lektion 22 von 107.
Go bietet eine integrierte Funktion namens new() an, die Speicher für einen Typ reserviert und einen Zeiger darauf zurückgibt. Der reservierte Speicher wird mit dem Nullwert des Typs initialisiert.
p := new(int) // reserviert Speicher für einen int
fmt.Println(*p) // 0 (Nullwert)
fmt.Println(p) // 0xc000018030 (Speicheradresse)Die Funktion new() nimmt einen Typ als Argument entgegen und gibt einen Zeiger auf einen neu zugewiesenen Nullwert dieses Typs zurück. Dies ist besonders nützlich, wenn Sie einen Zeiger benötigen, aber keine vorhandene Variable haben, auf die Sie verweisen können.
Bei Structs erzeugt new() einen Pointer auf ein Struct, wobei alle Felder auf ihre Nullwerte gesetzt sind.
type Person struct {
Name string
Age int
}
p := new(Person)
fmt.Println(p.Name) // "" (leerer String)
fmt.Println(p.Age) // 0Vielleicht fragen Sie sich, wann Sie new() gegenüber dem Adressoperator & verwenden sollten. Beide unten aufgeführten Ansätze sind gleichwertig:
// Verwendung von new()
p1 := new(Person)
// Verwendung des Adressoperators mit Literal
p2 := &Person{}Die &Person{}-Syntax ist in der Praxis gebräuchlicher, da sie es ermöglicht, Felder gleichzeitig zu initialisieren. Verwenden Sie new(), wenn Sie gezielt eine Nullwert-Instanz wünschen und eine explizite Speicherallokations-Semantik bevorzugen.
Aufgabe
EinfachLassen Sie uns einen Konfigurationsmanager erstellen, der demonstriert, wie new() Speicher reserviert und Structs mit ihren Nullwerten initialisiert. Sie werden sehen, wie sich dieser Ansatz von der Verwendung des Adressoperators mit einem Struct-Literal unterscheidet.
Sie werden Ihren Code in zwei Dateien organisieren:
config.go: Definieren Sie einServerConfigStruct mit den FeldernHost(string),Port(int),MaxConnections(int) undDebugMode(bool). Erstellen Sie zwei Funktionen:NewServerConfig, dienew()verwendet, um eineServerConfigzu reservieren und den Pointer direkt zurückgibt (mit allen Nullwerten)ConfigureServer, die einen*ServerConfigPointer zusammen mit einem Host-String und einem Port-Integer entgegennimmt und dann diese Felder in der Konfiguration über den Pointer setzt
DisplayMethode für*ServerConfighinzu, die einen formatierten String mit allen Konfigurationswerten zurückgibt.main.go: Lesen Sie einen Host und einen Port von der Eingabe ein. Erstellen Sie zuerst eine Konfiguration mitNewServerConfig()und zeigen Sie diese an, um die Nullwerte zu demonstrieren. Verwenden Sie dannConfigureServer, um den Host und den Port zu setzen, und zeigen Sie die Konfiguration erneut an, um die aktualisierten Werte zu sehen.
Die folgenden Eingaben werden bereitgestellt:
- Zeile 1: Hostname (string)
- Zeile 2: Portnummer (integer)
Ihre Display Methode sollte einen String in genau diesem Format zurückgeben:
Host: [Host]
Port: [Port]
MaxConnections: [MaxConnections]
DebugMode: [DebugMode]Geben Sie die Display-Ausgabe zweimal aus – einmal vor der Konfiguration (mit den Nullwerten) und einmal nach der Konfiguration (mit dem aktualisierten Host und Port).
Zum Beispiel, bei der Eingabe von localhost und 8080, sollte Ihre Ausgabe wie folgt aussehen:
Host:
Port: 0
MaxConnections: 0
DebugMode: false
Host: localhost
Port: 8080
MaxConnections: 0
DebugMode: falseBeachten Sie, dass die erste Anzeige alle Nullwerte zeigt (leerer String, 0, 0, false), da new() alles mit Nullwerten initialisiert. Nach dem Aufruf von ConfigureServer ändern sich nur der Host und der Port, während die anderen Felder bei ihren Nullwerten bleiben.
Spickzettel
Die Funktion new() reserviert Speicher für einen Typ und gibt einen Zeiger darauf zurück, der auf den Nullwert des Typs initialisiert ist:
p := new(int) // allocates memory for an int
fmt.Println(*p) // 0 (zero value)
fmt.Println(p) // 0xc000018030 (memory address)Bei Structs erstellt new() einen Zeiger auf ein Struct, wobei alle Felder auf ihre Nullwerte gesetzt sind:
type Person struct {
Name string
Age int
}
p := new(Person)
fmt.Println(p.Name) // "" (empty string)
fmt.Println(p.Age) // 0Die Verwendung von new() im Vergleich zum Adressoperator & - beide sind äquivalent:
// Using new()
p1 := new(Person)
// Using address operator with literal
p2 := &Person{}Die Syntax &Person{} ist gebräuchlicher, da sie die Initialisierung von Feldern zum Zeitpunkt der Erstellung ermöglicht. Verwenden Sie new(), wenn Sie eine Instanz mit Nullwerten und expliziter Speicherallokations-Semantik wünschen.
Probier es selbst
package main
import (
"fmt"
)
func main() {
// Eingabe lesen
var host string
var port int
fmt.Scanln(&host)
fmt.Scanln(&port)
// TODO: Erstelle eine Konfiguration mit NewServerConfig() und zeige sie an
// Dies wird die Nullwerte anzeigen
// TODO: Verwende ConfigureServer, um host und port zu setzen
// TODO: Zeige die Konfiguration erneut an, um die aktualisierten Werte anzuzeigen
}
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