The any constraint

Previously we illustrated how to write a function that can sum both int and int64 types (Go playground):

  1. // Sum returns the sum of the provided arguments.
  2. func Sum[T int | int64](args ...T) T {
  3. var sum T
  4. for i := 0; i < len(args); i++ {
  5. sum += args[i]
  6. }
  7. return sum
  8. }

But why limit the function only int and int64? One way to increase the number of supported types is by continuing to use the | operator:

  1. func Sum[T int | int8 | int32 | int64](args ...T) T

However, this would become cumbersome if we wanted to include any numeric types. Huh, any? Is there not some new any identifier in Go? Can we use it to rewrite Sum[T](...T) T? Let’s try (Go playground):

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. // Sum returns the sum of the provided arguments.
  6. func Sum[T any](args ...T) T {
  7. var sum T
  8. for i := 0; i < len(args); i++ {
  9. sum += args[i]
  10. }
  11. return sum
  12. }
  13. func main() {
  14. fmt.Println(Sum([]int{1, 2, 3}...))
  15. fmt.Println(Sum([]int8{1, 2, 3}...))
  16. fmt.Println(Sum([]uint32{1, 2, 3}...))
  17. fmt.Println(Sum([]float64{1.1, 2.2, 3.3}...))
  18. fmt.Println(Sum([]complex128{1.1i, 2.2i, 3.3i}...))
  19. }

Unfortunately the above program will fail to compile with the following error:

  1. ./prog.go:11:3: invalid operation: operator + not defined on sum (variable of type T constrained by any)

The any identifier is equivalent to the empty interface in all ways. Thus T in the above example might not represent a type for which the addition operator is valid.

Instead we need a type that represents all, possible numeric types…


Next: Composite constraints