chapter six

6 Generics

 

This chapter covers

  • How to use generics in Go
  • Creating generics with interfaces and structs
  • Defining type parameters for generics
  • Creating functions with generics
  • Using generics with the standard library

Computer science is built on various layers of abstraction. Electrical pulses lead to binary code, which leads to assembly code, and so on. In the last chapter, we looked at abstractions in the form of types, but in this section, we will explore another layer of abstraction on top of that, known as generics.

Generics allow you to define functions, types, and interfaces with type parameters, enabling the same code to operate on different data types while maintaining strict compile-time type safety. Introduced in Go 1.18, generics let you write reusable algorithms and data structures without duplicating code for each specific type or sacrificing compile-time safety.

In this chapter, we will explore the core concepts and practical applications of generics in Go by examining a set of generic collection types and utility functions (lists, sets, and maps), starting with how type parameters work and working up to increasingly powerful patterns.

6.1 Typed parameters in generics

To see why generics matter, consider the recipe application we built in the previous chapter. Suppose you want a function that filters a slice down to only the elements that match some condition. Without generics, you would need separate functions for every type, as illustrated in the following code:

6.1.1 Using interface constraints

6.1.2 Defining custom constraints

6.1.3 Using underlying types with tilde (~)

6.1.4 Summary of type constraints

6.2 Implementing generic functions

6.3 Implementing generic interfaces

6.4 Multiple type parameters

6.5 Limitations and considerations

6.5.1 Performance considerations

6.5.2 Limitations of Go generics

6.5.3 Common gotchas

6.5.4 When to use generics

6.5.5 Backward compatibility