What is a generic?

A generic is a symbol that represents one or more concrete types. Whereas variables are placeholders for referencing values, generics are placeholders for concrete types (there is a major difference which will be covered later). For example, the following code declares a variable and assigns it a value:

  1. var x int // declare "x"
  2. x = 2 // assign "x" the value of "2"

A developer can now refer to the value 2 using the variable x and/or assign a different value to x. In other words, the variable x:

  • can be used in any operation that takes a whole number
  • can be assigned the value of any whole number

In the same way, a generic type:

  • can be used in any operation in place of the concrete type(s) the generic type represents
  • can be assigned any value that is valid for the concrete type(s) the generic type represents

The following function is a quick and easy way to return the sum of zero to many int values:

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

However, what if a developer wants to implement the same logic for int64? For uint32? Before generics it would likely mean:

  • Using the empty interface and asserting type (Go playground),
  • or multiple functions, likely with the intended type name as their suffix (Go playground).

What is needed is some way to rewrite the original Sum function in a generic fashion so that it can:

  • be friendly to developers writing code (take multiple types)
  • provide compile-time type safety
  • provide runtime type safety

And that is exactly what Golang generics provides. Please keep reading to learn how to write a generic version of the Sum function.


Next: Syntax