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))
}
CodePudding user response:
comparable
is the constraint for types that support equality operators ==
and !=
. The generics proposal defines this in Comparable types in constraints:
To do this we introduce a new predeclared type constraint:
comparable
. The type set of the comparable constraint is the set of all comparable types. This permits the use of==
and!=
with values of that type parameter.
Notably, this includes anything that can be used as a map key, including arrays, structs with comparable fields and interfaces that box comparable values.
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.
Based on the current tip, the standard library constraint that supports the order operators such as >
and <
is constraints.Ordered
, defined as:
type Ordered interface {
Integer | Float | ~string
}