Sometime back we wrote a post explaining why there is no max/min function support for integers in GoLang, one of the reasons is that no overloading is supported and the function name has been used for other numeric types float64
. To solve this problem and make max/min function support integer as well, either GoLang should support overloading like in Java or the same set of functions need to be created in a different package other than standard math
. These don't look like good options as overloading is more a OOP concept and supporting the same set of functions in a different package doesn't sound scalable.
Is there other way to help out? Yes it is and it can be achieved with the soon to come new feature added in GoLang - Generics. This is some feature commonly available in other languages such as Java but not supported in GoLang due to design philosophy of GoLang.
With generics, a single function can be created for different data types with same logic operation. For example, when finding max or min of two numeric values, the operation is the same, hence we can create a function which can compare the two values and get the max or min of them no matter whether they both are integers or float numbers. To write this function, based on current generics proposal, it would be like:
package main
import (
"fmt"
)
type Numeric interface {
type int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64
}
func min[T Numeric](a, b T) T {
if a < b {
return a
}
return b
}
func max[T Numeric](a, b T) T {
if a > b {
return a
}
return b
}
func main() {
fmt.Println(min(45, 74))
fmt.Println(max(4.141, 2.01))
}
GoLang does support a new constraint for data type as any
which means any type. However for max/min, the data type should support doing comparison with >, < and == operators and hence we can create a custom type Numeric
which can be any of the declared numeric data types defined. All these types support <. > and ==.
When defining the max/min function, it just take a generic data type T in the square bracket. And parameter a and b are type of T and return value has the same data type T.
When calling the function, we just need to pass the numeric values we want no matter they are int
or float
, they would just work and return expected value. Above example will produce below output:
45
4.141
If we define the max/min function with any type, it would not pass compilation as it would fail type check since not every data type supports the <, > and == operators.
func min[T any](a, b T) T {
if a < b {
return a
}
return b
}
func max[T any](a, b T) T {
if a > b {
return a
}
return b
}
type checking failed for main
prog.go2:12:5: cannot compare a < b (operator < not defined for T)
prog.go2:19:5: cannot compare a > b (operator > not defined for T)
When generic is officially supported, we believe that the current max/min functions in math
package would be rewritten using generics.
The code for generic support has been in Go 1.17 and it would not be officially release until Go 1.18. But in Go 1.17, you should be able to play around with it. Stay tuned.
To understand more about generics, can refer to the discussion on Github.