📐 1. Eigene Datentypen mit struct
Go kennt keine Klassen oder Vererbungshierarchien. Daten werden in Structs gekapselt. Konstruktoren werden idiomatischerweise als Factory-Funktionen mit Präfix New implementiert:
type User struct {
ID int
Username string
Email string
Active bool
}
// Konstruktor-Funktion: Gibt Zeiger auf neuen User zurück
func NewUser(id int, username, email string) *User {
return &User{
ID: id,
Username: username,
Email: email,
Active: true, // Standardmäßig aktiv
}
}
Ein Struct ist wie das Antragsformular für einen Firmenausweis: Es legt fest, welche Felder existieren. Der Konstruktor NewUser ist das Bürgerbüro, das das Formular ausfüllt, standardmäßig abstempelt (Active: true) und dir die laminierte Karte (den Pointer *User) überreicht.
🎯 2. Value-Receiver vs. Pointer-Receiver
Methoden werden an Typen gebunden. Die Wahl des Receivers entscheidet darüber, ob auf einer Kopie gearbeitet wird oder der ursprüngliche Speicher mutiert werden kann:
| Receiver-Typ | Syntax | Verhalten & Wann nutzen? |
|---|---|---|
| Value-Receiver | func (u User) Info() string |
Erzeugt eine Kopie. Kann Originaldaten nicht verändern. Ideal für reine Lese-Operationen bei kleinen Structs. |
| Pointer-Receiver | func (u *User) SetEmail(e string) |
Arbeitet auf der Speicheradresse. Kann Felder mutieren und vermeidet Kopieraufwand bei großen Structs. |
// 1. Value-Receiver (Read-Only Kopie):
func (u User) Info() string {
return fmt.Sprintf("User #%d: %s <%s>", u.ID, u.Username, u.Email)
}
// 2. Pointer-Receiver (Mutiert den Original-Zustand):
func (u *User) Deactivate() {
u.Active = false
}
🧩 3. Komposition statt Vererbung: Struct Embedding
In Go erweitern wir Typen durch Embedding (anonyme Einbettung). Felder und Methoden des eingebetteten Typs werden automatisch nach oben durchgereicht (Promoted Fields/Methods):
type AdminUser struct {
User // Eingebettetes Struct (Anonymous Field)
Role string
Level int
}
admin := &AdminUser{
User: *NewUser(1, "root", "admin@cloud.local"),
Role: "SuperAdmin",
Level: 10,
}
// Direkter Zugriff auf User-Felder und Methoden:
fmt.Println(admin.Username) // Direkter Zugriff dank Promotion
fmt.Println(admin.Info()) // Ruft User.Info() auf