Golang / GoLang Interfaces and Object Oriented Interview Questions
How do generics relate to interfaces in Go 1.18+ and what are type constraints?
Go 1.18 extended the interface syntax so interfaces can serve as type constraints for generic functions and types. A constraint specifies which types a type parameter can be. Constraints are just interfaces β but now interfaces can include concrete type lists in addition to method sets.
// Constraint: any type with a < operator (from golang.org/x/exp/constraints) type Ordered interface { ~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~float32 | ~float64 | ~string } // Generic function constrained by Ordered func Min[T Ordered](a, b T) T { if a < b { return a } return b } fmt.Println(Min(3, 5)) // 3 Γ’ΒΒ T inferred as int fmt.Println(Min(3.14, 2.71)) // 2.71 Γ’ΒΒ T inferred as float64 fmt.Println(Min("foo", "bar")) // bar Γ’ΒΒ T inferred as string // The ~ (tilde) prefix means: any type whose underlying type is int type Celsius float64 Min(Celsius(20), Celsius(30)) // works because ~float64 matches Celsius // Interface as both constraint and regular interface type Stringer interface { String() string } func Describe[T Stringer](v T) string { return ">> " + v.String() } // Same interface used as constraint (generic) and variable type (runtime) var s Stringer = Color(Red) // runtime interface variable result := Describe(Color(Red)) // compile-time generic instantiation // any is also a valid constraint Γ’ΒΒ equivalent to interface{} func Keys[K comparable, V any](m map[K]V) []K { keys := make([]K, 0, len(m)) for k := range m { keys = append(keys, k) } return keys }
The key distinction: when an interface with a type list (e.g., ~int | ~float64) is used as a regular variable type, only method calls are allowed β the type list restricts which types can satisfy it. When used as a type constraint, the full type list is available to the compiler for optimisation and operator permissions (like <).
More Related questions...