Go Generics: The Long Road to Reusability (and the Debates That Follow)

“Love It or Hate It?” - The Verdict on Go’s New Generics Feature

I. The “Wait, Go Has Generics Now?!” Moment

Remember meticulously crafting CopyIntsCopyStrings, and CopyFloats? Or perhaps you recall the elaborate dances with interface{} trying to squeeze some reusability out of your Go code? If so, prepare yourself. Go has undergone a significant evolution.

What are we even talking about?

Go 1.18. These two digits marked a watershed moment: the arrival of Generics!

The siren song of generics? To construct adaptable, reusable, and type-safe code capable of operating across a spectrum of types, liberating us from the tyranny of bespoke implementations. Less boilerplate, more horsepower!

Generics 101: The Syntax Scoop

At the heart of the matter lies Type Parameters: these serve as placeholders for types, demarcated by square brackets []. Think of them as symbolic stand-ins, to be concretized later.

Consider a generic function, PrintSlice, designed to output the contents of a slice, irrespective of its element type.

1
2
3
4
5
6
7
8
9
10
11
12
func PrintSlice[T any](s []T) {
for _, v := range s {
fmt.Println(v)
}
}

// Usage examples:
ints := []int{1, 2, 3}
PrintSlice(ints) // Output: 1 2 3

strings := []string{"hello", "world"}
PrintSlice(strings) // Output: hello world

The magic here is that T infers its type from the slice you pass in, eliminating the need for explicit type specifications.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
type List[T any] struct {
data []T
}

func (l *List[T]) Add(item T) {
l.data = append(l.data, item)
}

// Usage:
intList := List[int]{}
intList.Add(10)

stringList := List[string]{}
stringList.Add("Go")

Here, the List struct can house integers today and strings tomorrow, all within a single, generic definition.

However, unbridled generality can lead to chaos. Constraints act as guardrails, dictating the permissible operations on our generic types.

any is the most permissive constraint. comparable is used to constrain a type to be comparable with == and !=. Custom constraints allow for even finer-grained control.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
type Number interface {
int | int64 | float64 // Union of types
}

func Sum[T Number](numbers []T) T {
var sum T
for _, n := range numbers {
sum += n
}
return sum
}

// Example usage:
ints := []int{1, 2, 3}
sumInts := Sum(ints) // sumInts is of type int

floats := []float64{1.1, 2.2, 3.3}
sumFloats := Sum(floats) // sumFloats is of type float64

II. A Decade of “Will They or Won’t They?” (The History Lesson)

Go, unveiled in 2009, was intentionally spartan, conspicuously devoid of generics. The guiding principle was simplicity.

Almost immediately, a chorus of voices arose, clamoring for generics. For years, this feature remained the most requested.

How to incorporate such a complex feature without compromising compilation speed, runtime performance, or the language’s intrinsic simplicity?

Years unfolded, marked by design proposals, fervent debates, and discarded concepts (such as “contracts”). Go resisted haste, favoring deliberation.

Finally, with Go 1.18 (Early 2022)! Generics arrived, ushering in a new era.

III. The Verdict: Love It or “Hmm, Let’s Talk” (Current Opinions & Controversies)

The Good Stuff (Why Devs are Cheering):

Reusable code for common patterns, data structures, and algorithms.

Compile-time error detection. No more runtime surprises stemming from interface{}.

The “But Wait, There’s More” (The Gripes & Debates):

  • Functional Limitations:
    • The absence of Generic Methods.
  • Syntax & Readability:
    • The [] syntax and the new ~ symbol may be unfamiliar.
  • The Go Philosophy Test:
    • Are we venturing into the realm of over-abstraction?
  • Hidden Gotchas: Pay heed to potential “performance surprises” linked to compiler inlining and escape analysis.
  • Ecosystem Lag: Tooling is still evolving.

IV. What’s Next for Generics in Go? (Future Developments)

  • Already Here (Recent Wins Since 1.18):
    • Go 1.21 (Aug 2023): Standard library enhancements with slicesmaps, and cmp packages.
    • Go 1.24 (Feb 2025): Generic type aliases for heightened expressiveness.
  • On the Horizon: Go 1.25 and Beyond!
    • BIG NEWS: Saying Goodbye to “Core Types” (Anticipated Aug 2025): This is a simplification, rendering generics more accessible.
    • Wishlist for the Future:
      • More expressive type constraints.
      • The advent of generic methods.
      • Expanded generic standard library support.

V. Wrapping It Up: Generics - A Game Changer, Still Evolving

Go generics have indubitably alleviated a significant burden for developers.

They are not devoid of idiosyncrasies and ongoing debates.

Experiment!

More

Recent Articles:

Random Article:


More Series Articles about You Should Know In Golang:

https://wesley-wei.medium.com/list/you-should-know-in-golang-e9491363cd9a

And I’m Wesley, delighted to share knowledge from the world of programming. 

Don’t forget to follow me for more informative content, or feel free to share this with others who may also find it beneficial. It would be a great help to me.

Give me some free applauds, highlights, or replies, and I’ll pay attention to those reactions, which will determine whether I continue to post this type of article.

See you in the next article. 👋

中文文章: https://programmerscareer.com/zh-cn/go-generics-03/
Author: Medium,LinkedIn,Twitter
Note: Originally written at https://programmerscareer.com/go-generics-03/ at 2026-01-05 00:39.
Copyright: BY-NC-ND 3.0

Hey Go Devs. Got a "panic" Attack on Your Performance? The Syntax of Generics in Go: Declaring Functions and Types

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×