unexpected-go

Unexpected Golang behaviors

View on GitHub

TL;DR

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.

Why?

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.