Direkt zum Hauptinhalt springen
eLearner.app
Modul 5 · Lektion 5 von 525/50 im Kurs~10 min
Lektionen des Moduls (5/5)

Das `New...`-Konstruktormuster

Go hat kein constructor-Schlüsselwort. Die Convention ist eine Fabrik Funktion, die einen ordnungsgemäß initialisierten Wert oder Zeiger zurückgibt. Von Der Name lautet normalerweise NewT (oder NewXxx).

Grundmuster: NewT

Go
type User struct {
    Name string
    Age  int
}

func NewUser(name string, age int) *User {
    return &User{Name: name, Age: age}
}

u := NewUser("Ada", 36)
fmt.Println(u.Name)

Vorteile gegenüber dem direkten Literal &User{...}:

  • Sie zentralisieren Validierung und Standardeinstellungen. – Sie können nicht exportierte Felder haben und diese nur über den Konstruktor füllen.
  • Sie können die Implementierung ändern, ohne Anrufer zu unterbrechen.

Konstruktor mit Validierung: (*T, Fehler)

Wenn die Initialisierung fehlschlagen kann, geben Sie (*T, error) zurück:

Go
import "errors"

func NewUser(name string, age int) (*User, error) {
    if name == "" {
        return nil, errors.New("nome obbligatorio")
    }
    if age < 0 {
        return nil, errors.New("eta non valida")
    }
    return &User{Name: name, Age: age}, nil
}

u, err := NewUser("Ada", 36)
if err != nil {
    // handle...
}

Dies ist das idiomatische Muster für jeden Konstruktor mit Voraussetzungen: Datenbankverbindung, Dateihandle, Serverkonfiguration usw.

Mehrere Konstruktoren

Wenn Sie mehrere „Möglichkeiten“ zum Konstruieren haben, verwenden Sie beschreibende Namen:

Go
func NewUser(name string) *User { ... }
func NewUserFromJSON(data []byte) (*User, error) { ... }
func NewAdmin() *User { ... }

Keine Überladung in Go: Der Name ist eindeutig.

Funktionsoptionen (erweiterte Einblicke)

Wenn viele optionale Parameter vorhanden sind, lautet das idiomatische Muster „Funktionsoptionen“:

Go
type Option func(*Server)

func WithPort(p int) Option {
    return func(s *Server) { s.Port = p }
}

func WithTLS(cert, key string) Option {
    return func(s *Server) { s.Cert, s.Key = cert, key }
}

func NewServer(opts ...Option) *Server {
    s := &Server{Port: 8080} // default
    for _, opt := range opts {
        opt(s)
    }
    return s
}

s := NewServer(WithPort(9000), WithTLS("c.pem", "k.pem"))

Es ist ausführlicher als ein Literal, lässt sich aber gut mit vielen optionalen Elementen skalieren Parameter und bewahrt die Abwärtskompatibilität (Hinzufügen eines neuen Option unterbricht bestehende Anrufer nicht).

Wenn Sie KEINEN Konstruktor benötigen

Wenn der Nullwert des Typs bereits nützlich ist, lassen Sie den Aufrufer den verwenden direktes wörtliches. Kanonisches Beispiel: sync.Mutex hat keinen Konstruktor, var m sync.Mutex ist bereits ein gebrauchsfertiger Mutex. Das Gleiche gilt für bytes.Buffer.

Die Regel lautet: „Nullwert sinnvoll machen“. Wenn du kannst, nein obligatorischer Konstruktor.

Probieren Sie es aus

Übung#go.m5.l5.e1
Versuche: 0Wird geladen…

Schreiben Sie die Factory-Funktion NewUser(name string, age int) *User, die &User{Name: name, Age: age} zurückgibt.

Editor wird geladen…
Hinweis anzeigen

Verwenden Sie das Literal `&User{...}`, um einen Zeiger zurückzugeben.

Lösung nach 3 Versuchen verfügbar

Übung#go.m5.l5.e2
Versuche: 0Wird geladen…

Verwandeln Sie NewUser in (Namenszeichenfolge) (*Benutzer, Fehler): Wenn Name == '' gibt Null zurück, Fehler.New('nome obbligatorio').

Editor wird geladen…
Hinweis anzeigen

Wenn Vorbedingungen vorliegen, geben Sie (*T, Fehler) zurück und geben Sie bei einem Fehler Null + Fehler zurück.

Lösung nach 3 Versuchen verfügbar

Quiz#go.m5.l5.e3
Bereit

Was ist die idiomatische Konvention für Konstruktoren in Go?

Go
// Which signature is more idiomatic?
Antwortoptionen

Zusammenfassung

  • Kein constructor: Verwenden Sie eine NewT-Funktion (oder New im gleichnamigen Paket).
  • Geben Sie *T für den einfachen Fall zurück; (*T, error) mit Vorbedingungen oder Validierung.
  • Bei Fehler: nil als Zeiger und den erklärenden Fehler als zweiten Wert zurückgeben.
  • Keine Überlastung; Verwenden Sie beschreibende Namen (NewUserFromJSON, NewAdmin).
  • „Nullwert nützlich machen“: Wenn Sie können, ist der Konstruktor unnötig.
  • Erweitertes Muster für viele optionale Parameter: Funktionsoptionen.