unexpected-go

Unexpected Golang behaviors

View on GitHub

TL;DR: There’s no math.Min(int, int) int function in golang, but there’s a builtin since go1.21

Just as easy as that, if you check the math package you won’t find a func Min(a, b int) int, neither a Max for ints, or for int64, etc.

However, since go1.21 there are min and max builtin functions.

What happened before?

Go does not support overloading of methods and operators. In many other languages you can define two functions as: min(a, b int) and min(a, b float64) but if you try this in go your program won’t compile. Since defining a bunch of different functions, one for each numerical type (MinInt, MinInt64, MinFloat64, …), is kind of messy and go is aimed at simplicity there is only Min(a, b float64).

Solutions

Casting ints into floats

There’s one for floats, and you’ll have to deal with that, either casting your ints to floats:

package main

import (
	"fmt"
	"math"
)

func main() {
	a := 1
	b := 2
	m := math.Min(float64(a), float64(b))
	
	fmt.Println(m)
}

(Note: casting ints into floats may result in loss of precision)

Custom specifics function

Defining your own min function everywhere is an option:

package main

import (
	"fmt"
)

func main() {
	a := 1
	b := 2
	m := min(a, b)

	fmt.Println(m)
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

Generics since Go 1.18

Go 1.18 introduced support for generics, and now a single function can be defined for all the comparable types:

package main

import (
	"fmt"

	"golang.org/x/exp/constraints"
)

func min[T constraints.Ordered](a, b T) T {
	if a < b {
		return a
	}
	return b
}

func main() {
	fmt.Println(min(1, 2))
	fmt.Println(min(1.5, 2.7))
}

You can define it for yourself, or use one of the multiple generic packages out there but remember the proverb: a little copying is better than a little dependency.