Reputation: 739
I am exploring go generics (1.18 beta), and have questions related to comparing two numerical values (a simple method that takes two values and returns a greater number).
For that, I am creating a custom numeric type that covers this type set (in the function getBiggerNumber
):
int | int8 | int16 | int32 | int64 | float32 | float64
However, added one more function but this time instead of using a custom type had used a comparable
built-in constraint (in the function getBiggerNumberWithComparable
).
But below code gives an error on this method as
"invalid operation: cannot compare t1 > t2 (operator > not defined on T)"?
Any idea why the >
operation did not work on built-in comparable types?
package main
import "fmt"
type numbers interface {
int | int8 | int16 | int32 | int64 | float32 | float64
}
func getBiggerNumber[T numbers](t1, t2 T) T {
if t1 > t2 {
return t1
}
return t2
}
func getBiggerNumberWithComparable[T comparable](t1, t2 T) T {
if t1 > t2 { // ./generics-sample.go:17:5: invalid operation: cannot compare t1 > t2 (operator > not defined on T)
return t1
}
return t2
}
func main() {
fmt.Println(getBiggerNumber(2.5, -4.0))
fmt.Println(getBiggerNumberWithComparable(2.5, -4.0))
}
Upvotes: 29
Views: 27523
Reputation: 44647
comparable
is the constraint for types that support equality operators ==
and !=
. The language spec defines this in Type constraints.
Notably, this includes anything that can be used as a map key, including arrays and structs with comparable fields. (Types where the comparison may panic at run time, e.g. interfaces, are excluded until Go 1.20).
It is true that in the Go language specifications, the comparison operators include order operators as (<
, >
, <=
, >=
). This choice of terminology probably is what confuses you. However the specs also disambiguate:
The equality operators
==
and!=
apply to operands that are comparable. The ordering operators<
,<=
,>
, and>=
apply to operands that are ordered.
Use cmp.Ordered
from the standard library.
The new cmp package defines the type constraint Ordered and two new generic functions Less and Compare that are useful with ordered types.
In Go 1.18 the available constraint that supports the order operators such as >
and <
is constraints.Ordered
1:
type Ordered interface {
Integer | Float | ~string
}
1: note that the package golang.org/x/exp
is experimental. Its contents aren't guaranteed to be backwards compatible with new Go releases, but you can always copy-paste the definitions you need into your own code
Upvotes: 58