Go Generics 2026: Typparameter, Constraints und Interview-Fragen
Dieser Artikel behandelt wichtige Go-Generics-Interview-Fragen für 2026, von grundlegenden Typparametern bis hin zu fortgeschrittenen Constraint-Mustern.

Go 1.18 führte im März 2022 Generics in die Sprache ein, und seitdem hat sich diese Funktion durch Go 1.21, 1.22 und darüber hinaus weiterentwickelt. Dieser Artikel behandelt wichtige Go-Generics-Interview-Fragen für 2026, von grundlegenden Typparametern bis hin zu fortgeschrittenen Constraint-Mustern, die in technischen Vorstellungsgesprächen häufig vorkommen.
Go Generics ermöglichen das Schreiben von Funktionen und Typen, die mit beliebigen Datentypen arbeiten und dabei die Typsicherheit zur Compile-Zeit gewährleisten. Im Gegensatz zu Interfaces, die Runtime-Type-Assertions verwenden, werden bei Generics die Typen zur Compile-Zeit aufgelöst, was bessere Performance und frühere Fehlererkennung bietet.
Typparameter in Go verstehen
Typparameter bilden die Grundlage von Go Generics. Ein Typparameter ist ein Platzhalter für einen Typ, der beim Verwenden der generischen Funktion oder des generischen Typs spezifiziert wird.
// Basic generic function with type parameter T
func PrintSlice[T any](items []T) {
for _, item := range items {
fmt.Println(item)
}
}
// Usage - type inference determines T automatically
func main() {
PrintSlice([]int{1, 2, 3}) // T is int
PrintSlice([]string{"a", "b"}) // T is string
}Die Syntax mit eckigen Klammern [T any] deklariert einen Typparameter T, der durch any eingeschränkt ist. Der Go-Compiler leitet den konkreten Typ aus den Argumenten ab, wodurch in den meisten Fällen keine explizite Typangabe erforderlich ist.
Häufige Interview-Frage: Was ist der Unterschied zwischen any und comparable?
Interviewer fragen häufig nach den eingebauten Constraints any und comparable. Das Verständnis ihrer Unterschiede demonstriert solides Generics-Wissen.
// any: accepts all types (alias for interface{})
func Process[T any](value T) T {
return value
}
// comparable: only types that support == and !=
func Contains[T comparable](slice []T, target T) bool {
for _, v := range slice {
if v == target { // This comparison requires comparable
return true
}
}
return false
}
// This compiles
Contains([]int{1, 2, 3}, 2)
// This fails: slices are not comparable
// Contains([][]int{{1}, {2}}, []int{1})Das comparable-Constraint beschränkt Typparameter auf Typen, die Gleichheitsoperatoren unterstützen. Slices, Maps und Funktionen sind ausgeschlossen, da Go für diese auf Sprachebene keine Gleichheit definiert.
Benutzerdefinierte Typconstraints mit Interfaces erstellen
Go verwendet Interfaces zur Definition benutzerdefinierter Constraints und erweitert damit, was generische Funktionen akzeptieren können. Die Go-Spezifikation definiert, wie Typelemente innerhalb von Constraint-Interfaces funktionieren.
// Custom constraint using type union
type Number interface {
int | int8 | int16 | int32 | int64 |
uint | uint8 | uint16 | uint32 | uint64 |
float32 | float64
}
// Generic function constrained to numeric types
func Sum[T Number](values []T) T {
var total T
for _, v := range values {
total += v // + operator works because all Number types support it
}
return total
}
func main() {
fmt.Println(Sum([]int{1, 2, 3})) // 6
fmt.Println(Sum([]float64{1.5, 2.5})) // 4.0
}Typvereinigungen mit | spezifizieren, welche exakten Typen das Constraint erfüllen. Dieser Ansatz bietet mehr Kontrolle als any und vermeidet gleichzeitig Runtime-Type-Assertions.
Interview-Frage: Den ~ Tilde-Operator in Constraints erklären
Der Tilde-Operator ~ in Constraints erfasst sowohl einen Typ als auch alle Typen mit diesem zugrunde liegenden Typ. Diese Frage testet das Verständnis von Gos Typsystem.
// ~int matches int and any type with int as underlying type
type Signed interface {
~int | ~int8 | ~int16 | ~int32 | ~int64
}
// Custom type with int as underlying type
type UserID int
type Temperature int64
func Abs[T Signed](value T) T {
if value < 0 {
return -value
}
return value
}
func main() {
var id UserID = -42
var temp Temperature = -10
fmt.Println(Abs(id)) // 42 - works because ~int matches UserID
fmt.Println(Abs(temp)) // 10 - works because ~int64 matches Temperature
}Ohne ~ würde das Constraint int nur den exakten Typ int erfassen, nicht benutzerdefinierte Typen wie UserID. Die Tilde erweitert das Constraint um abgeleitete Typen und macht generischen Code flexibler.
Bereit für deine Go-Interviews?
Übe mit unseren interaktiven Simulatoren, Flashcards und technischen Tests.
Generische Typen: Structs und Methoden
Generische Typen gehen über Funktionen hinaus zu Structs und Methoden. Dieses Muster erscheint häufig in Datenstruktur-Implementierungen.
// Generic Stack type
type Stack[T any] struct {
items []T
}
// Push adds an element to the stack
func (s *Stack[T]) Push(item T) {
s.items = append(s.items, item)
}
// Pop removes and returns the top element
func (s *Stack[T]) Pop() (T, bool) {
if len(s.items) == 0 {
var zero T // Zero value for type T
return zero, false
}
index := len(s.items) - 1
item := s.items[index]
s.items = s.items[:index]
return item, true
}
func main() {
intStack := Stack[int]{}
intStack.Push(10)
intStack.Push(20)
val, ok := intStack.Pop() // val=20, ok=true
}Zu beachten ist, dass Methoden auf generischen Typen den Typparameter in Klammern wiederholen müssen, aber keine neuen Typparameter einführen können. Der Receiver (s *Stack[T]) bindet die Methode an die spezifische Instanziierung von Stack.
Interview-Frage: Warum können Methoden keine eigenen Typparameter haben?
Go verbietet zusätzliche Typparameter bei Methoden, eine Designentscheidung, die Entwickler überrascht, die von Sprachen wie Java oder C# kommen. Der Go Generics Proposal erklärt, dass diese Einschränkung existiert, um das Typsystem handhabbar zu halten.
// This is NOT valid Go code
type Container[T any] struct {
value T
}
// ERROR: methods cannot have type parameters
// func (c *Container[T]) Transform[U any](fn func(T) U) U {
// return fn(c.value)
// }
// Valid alternative: use a standalone function
func Transform[T, U any](c *Container[T], fn func(T) U) U {
return fn(c.value)
}Die Lösung verwendet Top-Level-Funktionen mit mehreren Typparametern anstelle von Methoden. Dieses Design hält den Method-Dispatch einfach und vermeidet komplexe Interaktionen zwischen Receiver-Typen und Methoden-Typparametern.
Typinferenz und Constraint-Inferenz
Gos Typinferenz reduziert die Ausführlichkeit beim Aufrufen generischer Funktionen. Das Verständnis, wann explizite Typargumente erforderlich sind, hilft beim Schreiben saubereren Codes.
func Map[T, R any](input []T, transform func(T) R) []R {
result := make([]R, len(input))
for i, v := range input {
result[i] = transform(v)
}
return result
}
func main() {
numbers := []int{1, 2, 3}
// Type inference: T=int, R=string inferred from arguments
strings := Map(numbers, func(n int) string {
return fmt.Sprintf("%d", n)
})
// Explicit types sometimes required for complex cases
// Map[int, string](numbers, converter)
}Die Typinferenz arbeitet von Funktionsargumenten zu Typparametern. Wenn der Compiler Typen nicht allein aus den Argumenten ableiten kann, lösen explizite Typargumente in eckigen Klammern die Mehrdeutigkeit auf.
Constraints-Paket: cmp und slices in der Standardbibliothek
Go 1.21 fügte das cmp-Paket mit dem Ordered-Constraint und Vergleichsfunktionen hinzu. Das slices-Paket demonstriert idiomatischen generischen Code in der Standardbibliothek.
import (
"cmp"
"slices"
)
func main() {
numbers := []int{3, 1, 4, 1, 5, 9}
// slices.Sort uses cmp.Ordered constraint internally
slices.Sort(numbers) // [1, 1, 3, 4, 5, 9]
// Binary search on sorted slice
index, found := slices.BinarySearch(numbers, 4)
// cmp.Compare returns -1, 0, or 1
result := cmp.Compare(3, 5) // -1
// cmp.Or returns first non-zero value
value := cmp.Or(0, 0, 42, 100) // 42
}Die Standardbibliothek-Dokumentation zeigt, wie diese Pakete Generics für typsichere Operationen auf geordneten Typen nutzen. Vertrautheit mit diesen Paketen demonstriert praktisches Generics-Wissen jenseits des theoretischen Verständnisses.
Interview-Frage: Implementierung eines generischen Caches
Eine häufige Interview-Übung fordert Kandidaten auf, einen generischen, thread-sicheren Cache zu implementieren. Dies testet Generics, Nebenläufigkeit mit dem sync-Paket und API-Design.
import (
"sync"
"time"
)
type Cache[K comparable, V any] struct {
mu sync.RWMutex
items map[K]cacheItem[V]
}
type cacheItem[V any] struct {
value V
expiration time.Time
}
func NewCache[K comparable, V any]() *Cache[K, V] {
return &Cache[K, V]{
items: make(map[K]cacheItem[V]),
}
}
func (c *Cache[K, V]) Set(key K, value V, ttl time.Duration) {
c.mu.Lock()
defer c.mu.Unlock()
c.items[key] = cacheItem[V]{
value: value,
expiration: time.Now().Add(ttl),
}
}
func (c *Cache[K, V]) Get(key K) (V, bool) {
c.mu.RLock()
defer c.mu.RUnlock()
item, exists := c.items[key]
if !exists || time.Now().After(item.expiration) {
var zero V
return zero, false
}
return item.value, true
}Diese Implementierung verwendet comparable für Keys (Map-Anforderung) und any für Values. Das separate cacheItem-Struct zeigt, wie generische Typen ineinander verschachtelt werden können. Thread-Sicherheit kommt von sync.RWMutex, ein Muster, das in Go-Nebenläufigkeits-Interviews behandelt wird.
Nullwerte und Typconstraints
Der Umgang mit Nullwerten in generischem Code erfordert das Verständnis, wie Go Variablen parametrisierter Typen initialisiert.
// Return zero value when slice is empty
func First[T any](slice []T) T {
if len(slice) == 0 {
var zero T // Zero value: 0 for int, "" for string, nil for pointers
return zero
}
return slice[0]
}
// Alternative: return pointer to avoid ambiguity
func FirstOrNil[T any](slice []T) *T {
if len(slice) == 0 {
return nil
}
return &slice[0]
}Das var zero T-Muster erstellt einen Nullwert für jeden Typ T. Für Typen, bei denen Null ein gültiger Wert ist (wie 0 für Integer), unterscheidet die Pointer-zurückgebende Variante zwischen "nicht gefunden" und "Null gefunden".
Fortgeschritten: Mehrere Constraints kombinieren
Komplexe generische Funktionen können erfordern, dass Typen mehrere Constraints erfüllen. Go handhabt dies durch Interface-Einbettung.
// Constraint requiring both ordering and string conversion
type Stringable interface {
String() string
}
type OrderedStringable interface {
cmp.Ordered
Stringable
}
// Alternative: use type parameters with multiple constraints inline
func PrintSorted[T interface{ cmp.Ordered; fmt.Stringer }](items []T) {
slices.Sort(items)
for _, item := range items {
fmt.Println(item.String())
}
}Interface-Einbettung kombiniert Constraints und erfordert, dass Typen alle eingebetteten Interfaces implementieren. Die Inline-Syntax interface{ A; B } bietet die gleiche Funktionalität ohne Deklaration eines benannten Constraint-Typs.
Fazit
- Typparameter mit
[T any]ermöglichen das Schreiben von wiederverwendbarem, typsicherem Code ohne Runtime-Reflection comparablebeschränkt auf Typen, die==und!=unterstützen, erforderlich für Map-Keys- Die
~-Tilde erfasst Typen mit einem spezifischen zugrunde liegenden Typ und erweitert die Constraint-Flexibilität - Benutzerdefinierte Constraints verwenden Typvereinigungen (
int | string) zur Spezifikation exakt erlaubter Typen - Methoden können keine eigenen Typparameter haben; Top-Level-Funktionen dienen als Alternative
- Die Standardbibliothek-Pakete
cmpundslicesdemonstrieren idiomatische generische Muster - Nullwerte über
var zero Tbehandeln leere oder fehlende Daten in generischen Funktionen - Thread-sichere generische Datenstrukturen kombinieren Generics mit sync-Primitiven
Fang an zu üben!
Teste dein Wissen mit unseren Interview-Simulatoren und technischen Tests.
Teilen
Verwandte Artikel

Go Fehlerbehandlung 2026: Patterns, Wrapping und technische Interviewfragen
Fehlerbehandlung in Go unterscheidet sich grundlegend von anderen Sprachen. Dieser Artikel behandelt Error Wrapping, Sentinel Errors und typische Interviewfragen.

Go und gRPC 2026: Hochleistungs-Microservices und Interview-Fragen
Umfassendes Go-gRPC-Tutorial mit Protocol Buffers, Streaming-RPCs, Interceptors, Produktions-Patterns und häufigen Backend-Interview-Fragen für 2026.

Go Design Patterns: Die wichtigsten Muster und Interview-Fragen fuer Go-Entwickler
Die sechs wichtigsten Go Design Patterns mit produktionsreifem Code: Functional Options, Strategy, Factory, Observer, Middleware und Struct Embedding. Inklusive typischer Interview-Fragen.