Summary of the Latest Go Generics Design Draft with Code Examples
This article summarizes the key changes in the new Go generics design draft, explaining type constraints, multiple type parameters, type lists, generic structs, and method‑based constraints, and includes practical Go code snippets to illustrate each feature.
The Go team announced the latest design draft for Go generics, providing detailed reasoning behind decisions and implementation details.
The goal of this article is to summarize the main upcoming changes and demonstrate the core functionality with code examples.
1. Type constraints in generic functions
// package decls, imports...
func arrayOf(type T)(elems ...T) []T {
arr := []T{}
for _, el := range elems {
arr = append(arr, el)
}
return arr
}
func main() {
strs := arrayOf("one", "two", "three", "four", "five")
fmt.Println(strs)
nums := arrayOf(1, 2, 3, 4, 5)
fmt.Println(nums)
}To add constraints to a generic type, you can require it to implement a specific interface:
// package decls, imports...
// Person, who implements fmt.Stringer...
func join(type T fmt.Stringer)(tokens []T, delim string) string {
res := ""
for _, token := range tokens {
if res != "" { res += delim }
res += token.String()
}
return res
}
func main() {
joined := join([]Person{Person{"Mike", "Jordan"}, Person{"Dave", "Stevens"}, Person{"John", "Doe"}}, ", ")
fmt.Println(joined)
}2. Multiple type parameters
// package decls, imports...
func mapAll(type T, R)(arr []T, mapFunc func(T) R) []R {
res := []R{}
for _, el := range arr {
res = append(res, mapFunc(el))
}
return res
}
func main() {
strs := mapAll([]int{1, 2, 3}, func(n int) string { return strconv.Itoa(n) })
fmt.Println(strs)
}3. Type lists and comparability
// package decls, imports...
type Ordered interface {
type int, int8, int16, int32, int64,
uint, uint8, uint16, uint32, uint64, uintptr,
float32, float64,
string
}
func Max(type T Ordered)(elems []T) T {
if len(elems) == 0 { var zero T; return zero }
max := elems[0]
for _, el := range elems {
if el > max { max = el }
}
return max
}
func main() {
res := Max([]int{1,5,3,10,4})
fmt.Println(res)
} // package decls, imports...
func Contains(type T comparable)(elems []T, target T) bool {
for _, elem := range elems {
if elem == target { return true }
}
return false
}
func main() {
fmt.Println(Contains([]int{1,2,3,4,5}, 4))
}4. Generic types (structs)
// package decls, imports...
type Stack(type T) struct {
buffer []T
}
func (v *Stack(T)) Push(elem T) { v.buffer = append(v.buffer, elem) }
func (v *Stack(T)) Pop() T {
res := v.buffer[len(v.buffer)-1]
v.buffer = v.buffer[:len(v.buffer)-1]
return res
}
func main() {
st := &Stack(int){}
st.Push(1); st.Push(2); st.Push(3)
fmt.Println(st.Pop())
fmt.Println(st.Pop())
fmt.Println(st.Pop())
}5. Constraints with methods and pointer types
// package decls, imports...
type Setter interface { Set(string) }
type Settable int
func (p *Settable) Set(s string) { i, _ := strconv.Atoi(s); *p = Settable(i) }
func FromStrings(type *T Setter)(s []string) []T {
result := make([]T, len(s))
for i, v := range s { result[i].Set(v) }
return result
}
func main() {
nums := FromStrings(Settable)([]string{"1","2","3"})
fmt.Println(nums)
}The article aims to provide a concise overview of the new generics draft, encouraging readers to consult the official design document for deeper insight.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
360 Tech Engineering
Official tech channel of 360, building the most professional technology aggregation platform for the brand.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
