# Go Generics in 2026: Type Parameters, Constraints en Sollicitatievragen > Dit artikel behandelt essentiële Go generics sollicitatievragen voor 2026, van basis type parameters tot geavanceerde constraint-patronen. - Published: 2026-07-08 - Updated: 2026-07-08 - Author: SharpSkill - Reading time: 5 min --- Go 1.18 introduceerde generics in de taal in maart 2022, en sindsdien is deze functionaliteit doorontwikkeld via Go 1.21, 1.22 en verder. Dit artikel behandelt essentiële Go generics sollicitatievragen voor 2026, van basis type parameters tot geavanceerde constraint-patronen die hiring managers vaak vragen. > **Wat zijn Go Generics?** > > Go generics maken het mogelijk om functies en types te schrijven die werken met elk datatype terwijl compile-time type safety behouden blijft. In tegenstelling tot interfaces die runtime type assertions gebruiken, worden bij generics de types tijdens compile-time opgelost, wat betere performance en eerdere foutdetectie biedt. ## Type Parameters in Go Begrijpen Type parameters vormen de basis van Go generics. Een type parameter is een placeholder voor een type dat wordt gespecificeerd wanneer de generieke functie of het generieke type wordt gebruikt. ```go // generic.go // 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 } ``` De syntax met vierkante haken `[T any]` declareert een type parameter `T` die beperkt is door `any`. Go's compiler leidt het concrete type af uit de argumenten, waardoor expliciete typespecificatie in de meeste gevallen overbodig wordt. ## Veelgestelde Sollicitatievraag: Wat is het Verschil tussen `any` en `comparable`? Interviewers vragen vaak naar de ingebouwde constraints `any` en `comparable`. Het begrijpen van hun verschillen demonstreert solide generics-kennis. ```go // constraints.go // 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}) ``` De `comparable` constraint beperkt type parameters tot types die gelijkheidsoperatoren ondersteunen. Slices, maps en functies zijn uitgesloten omdat Go geen gelijkheid voor deze op taalniveau definieert. ## Aangepaste Type Constraints Maken met Interfaces Go gebruikt interfaces om aangepaste constraints te definiëren, waardoor uitgebreid wordt wat generieke functies kunnen accepteren. De [Go-specificatie](https://go.dev/ref/spec#Type_constraints) definieert hoe type-elementen werken binnen constraint-interfaces. ```go // number.go // 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 } ``` Type unions met `|` specificeren welke exacte types aan de constraint voldoen. Deze aanpak biedt meer controle dan `any` terwijl runtime type assertions worden vermeden. ## Sollicitatievraag: De `~` Tilde-operator in Constraints Uitleggen De tilde-operator `~` in constraints matcht zowel een type als alle types met dat onderliggende type. Deze vraag test begrip van Go's typesysteem. ```go // underlying.go // ~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 } ``` Zonder `~` zou de constraint `int` alleen het exacte type `int` matchen, niet aangepaste types zoals `UserID`. De tilde breidt de constraint uit om afgeleide types te includeren, waardoor generieke code flexibeler wordt. ## Generieke Types: Structs en Methods Generieke types gaan verder dan functies naar structs en methods. Dit patroon verschijnt frequent in datastructuur-implementaties. ```go // stack.go // 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 } ``` Merk op dat methods op generieke types de type parameter tussen haakjes moeten herhalen maar geen nieuwe type parameters kunnen introduceren. De receiver `(s *Stack[T])` bindt de method aan de specifieke instantiatie van `Stack`. ## Sollicitatievraag: Waarom Kunnen Methods Geen Eigen Type Parameters Hebben? Go verbiedt extra type parameters op methods, een ontwerpbeslissing die ontwikkelaars verrast die komen van talen zoals Java of C#. De [Go generics proposal](https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md) legt uit dat deze beperking bestaat om het typesysteem hanteerbaar te houden. ```go // 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) } ``` De workaround gebruikt top-level functies met meerdere type parameters in plaats van methods. Dit ontwerp houdt method dispatch eenvoudig en vermijdt complexe interacties tussen receiver-types en method type parameters. ## Type Inference en Constraint Inference Go's type inference vermindert de verbositeit bij het aanroepen van generieke functies. Begrijpen wanneer expliciete type-argumenten nodig zijn helpt bij het schrijven van schonere code. ```go // inference.go 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) } ``` Type inference werkt van functie-argumenten naar type parameters. Wanneer de compiler types niet alleen uit argumenten kan afleiden, lossen expliciete type-argumenten tussen vierkante haken de ambiguïteit op. ## Constraints Package: `cmp` en `slices` in de Standaardbibliotheek Go 1.21 voegde het `cmp`-package toe met de `Ordered` constraint en vergelijkingsfuncties. Het `slices`-package demonstreert idiomatische generieke code in de standaardbibliotheek. ```go // stdlib.go 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 } ``` De [standaardbibliotheek-documentatie](https://pkg.go.dev/cmp) toont hoe deze packages generics benutten voor type-veilige operaties op geordende types. Bekendheid met deze packages demonstreert praktische generics-kennis voorbij theoretisch begrip. ## Sollicitatievraag: Een Generieke Cache Implementeren Een veelvoorkomende sollicitatie-oefening vraagt kandidaten om een generieke, thread-safe cache te implementeren. Dit test generics, concurrency met het [sync-package](/technologies/go/interview-questions/sync-primitives) en API-ontwerp. ```go // cache.go 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 } ``` Deze implementatie gebruikt `comparable` voor keys (map-vereiste) en `any` voor values. De aparte `cacheItem`-struct toont hoe generieke types in elkaar kunnen worden genest. Thread-veiligheid komt van `sync.RWMutex`, een patroon dat wordt behandeld in Go-[concurrency-sollicitaties](/technologies/go/interview-questions/concurrency-patterns). ## Zero Values en Type Constraints Het omgaan met zero values in generieke code vereist begrip van hoe Go variabelen van geparametriseerde types initialiseert. ```go // zero.go // 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] } ``` Het `var zero T`-patroon creëert een zero value voor elk type `T`. Voor types waar nul een geldige waarde is (zoals `0` voor integers), onderscheidt de pointer-teruggevende variant tussen "niet gevonden" en "nul gevonden". ## Geavanceerd: Meerdere Constraints Combineren Complexe generieke functies kunnen vereisen dat types aan meerdere constraints voldoen. Go handelt dit af via interface-embedding. ```go // combined.go // 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-embedding combineert constraints, waarbij types alle ingebedde interfaces moeten implementeren. De inline syntax `interface{ A; B }` biedt dezelfde functionaliteit zonder een benoemd constraint-type te declareren. ## Conclusie - Type parameters met `[T any]` maken het mogelijk herbruikbare, type-veilige code te schrijven zonder runtime reflection - `comparable` beperkt tot types die `==` en `!=` ondersteunen, vereist voor map keys - De `~` tilde matcht types met een specifiek onderliggend type, wat constraint-flexibiliteit uitbreidt - Aangepaste constraints gebruiken type unions (`int | string`) om exacte toegestane types te specificeren - Methods kunnen geen eigen type parameters hebben; gebruik top-level functies als alternatief - Standaardbibliotheek-packages `cmp` en `slices` demonstreren idiomatische generieke patronen - Zero values via `var zero T` handelen lege of ontbrekende data af in generieke functies - Thread-veilige generieke datastructuren combineren generics met sync-primitieven --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/nl/blog/go/go-generics-type-parameters-constraints-interview-questions