Generic Programming in Golang

Source : [Tucker’s Go Programming]

What is Generic Programming ?

Let’s know about generic programming, and also why we should use it.

Static polymorphism supports the concept of generic programming.

The definition of generalized programming is not generally agreed. (As if there is no definition of object-oriented programs that everyone accepts )

But we can understand generic programming by comparing simple examples.

Let’s see add function below.

func add(a, b int) int {
  return a + b
}

Since Golang is a strong type language, an error will occur if you insert a non-int type parameter as shown in the example below.

func main() {
  result := add(0.25, 0.75)
  fmt.Println(result)
}

As such, making functions separately for each type, such as int8, int16, float64, is a very cumbersome task.

And if the function behavior changes, the maintenance is not good because you have to change all the functions.

Generic programming allows you to address this issue as follows:

func add[T constraints.Integer | contraints.Float](a, b T) T {
  return a + b
}

Generic functions are functions that operate on different types through type parameters, such as the add() function discussed earlier.

// Define Function name(Primrose) and type parameter(T constraint)
func Primrose[T contraint](p T) {
  ...
}

Generic functions are defined as above.

Write down the func function keyword and then the function name.

Then open the brackets and write down the type parameters.

The type parameter is the parameter name, and in the figure above, T is the parameter name.

Then write down the type limit. You can write multiple type parameters as needed.

Then close the brackets, open the brackets, and write inputs and outputs like a normal function.

The type parameter name used for the type parameter can be used instead of a specific type.

Simple example

func Print[T ant](a, b T) {
  fmt.Println(a, b)
}

func main() {
  // OK
  Print(1, 2)
  Print(3.14, 1.43)
  Print("Hello", "World")

  // Error !
  Print(1, "Hello")
}

Solution

func Print[T1 any, T2 any](a T1, b T2) {
  fmt.Println(a, b)
}

func PrintInterface(a, b interface{}) {
  fmt.Println(a, b)
}

func main() {
  // ... Two function will get same result.
}

We can also apply type restriction

func add[T Integer](a, b T) T {
  return a + b 
}

Advanced type restriction

type Integer interface {
  ~ int8 | ~int16 | ~int32 | ~int64 | ~int
}

func add[T Integer](a, b T) T {
  return a + b
}

type MyInt int

func main() {
  // OK! 
  add(1, 2)
  var a MyInt = 3
  var b MyInt = 5
  add(a, b)
}

Last updated