🦆 1. Implizite Implementierung (Duck Typing)
In Go gibt es kein implements-Schlüsselwort. Ein Struct erfüllt ein Interface automatisch, sobald es alle geforderten Methoden mit exakter Signatur besitzt:
// 1. Interface definieren (Methoden-Set)
type Greeter interface {
Greet(name string) string
}
// 2. Beliebiges Struct
type GermanBot struct{}
// 3. Methode implementieren -> Erfüllt Greeter implizit!
func (g GermanBot) Greet(name string) string {
return "Guten Tag, " + name + "!"
}
// 4. Polymorphe Funktion
func RunGreeter(g Greeter, user string) {
fmt.Println(g.Greet(user))
}
Ein Interface ist wie eine Steckdose in der Wand: Es definiert lediglich die Form der Löcher (die Funktionssignaturen). Ob du einen Föhn, ein MacBook-Ladekabel oder eine Kaffeemaschine einsteckst, ist der Steckdose egal – solange der Stecker passt, fließt Strom!
🔍 2. Type Assertions & Type Switches
Wenn du mit einem Interface arbeitest, kannst du den konkreten darunterliegenden Typ mit Type Assertions prüfen:
// 1. Sichere Type Assertion mit Comma-OK:
var x any = "Hallo Go"
str, ok := x.(string)
if ok {
fmt.Println("Länge des Strings:", len(str))
}
// 2. Type Switch:
func Describe(val any) string {
switch v := val.(type) {
case int:
return fmt.Sprintf("Ganzzahl: %d", v*2)
case string:
return fmt.Sprintf("String: %s (Länge: %d)", v, len(v))
case bool:
return fmt.Sprintf("Boolean: %t", v)
default:
return "Unbekannter Typ"
}
}
🎯 Aufgaben & Checkliste in aufgabe.go
Die Go-Standardbibliothek brilliert durch winzige Interfaces wie io.Reader (1 Methode) oder fmt.Stringer (1 Methode). Halte Interfaces so klein und präzise wie möglich!