GO / CHAPTER 09

Generic functions and useful constraints

Advanced

Reuse an algorithm while keeping its operations type checked.

By the end of this chapter

  • Connect constraints to allowed operations
  • Use comparable for equality
  • Keep generic results independent when required

The idea

A generic function declares type parameters so one implementation can serve several concrete types. Its constraint describes which operations are legal for every permitted type. comparable permits equality comparisons and map keys; it does not promise arithmetic or ordering. A useful constraint follows from the algorithm’s needs rather than from every operation you might eventually want to add.

Generics do not change ownership or copying rules. A function that returns a fresh slice can still share pointer-valued elements with its input. Describe whether independence concerns only the outer collection or the nested values too. Start with a small reusable operation, such as retaining first occurrences, and make its order and empty-input behavior explicit before making the implementation generic.

Go example
package main
import "fmt"
func Count[T comparable](xs []T, target T) int { n:=0; for _,x:=range xs { if x==target { n++ } }; return n }
func main(){ fmt.Println(Count([]string{"a","b","a"},"a")); fmt.Println(Count([]int{},3)) }
Result
2
0

The equality constraint supports both element types. The empty slice leaves the initialized count unchanged.

Try it yourself

Implement a generic first-occurrence deduplicator using a map[T]bool with T comparable.

Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.

CHECK YOUR UNDERSTANDING

Chapter checkpoint

Why does Count require comparable rather than any?