英文:
In Go generics, why can't I use comparable constraint with order operators?
问题
我正在探索go泛型(1.18 beta),并且有关于比较两个数值的问题(一个简单的方法,接受两个值并返回较大的数)。为此,我正在创建一个自定义的数值类型,涵盖了以下类型集合(在函数getBiggerNumber
中):
int | int8 | int16 | int32 | int64 | float32 | float64
然而,我添加了另一个函数,但这次不是使用自定义类型,而是使用了一个comparable
内置约束(在函数getBiggerNumberWithComparable
中)。
但是下面的代码在这个方法上报错,错误信息为:
"invalid operation: cannot compare t1 > t2 (operator > not defined on T)"?
有任何想法为什么在内置的可比较类型上>
操作无法工作?
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))
}
英文:
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))
}
答案1
得分: 33
comparable
是对支持相等运算符==
和!=
的类型的约束。语言规范在类型约束中定义了这一点。
值得注意的是,这包括可以用作映射键的任何内容,包括具有可比较字段的数组和结构体。(在运行时可能导致恐慌的比较,例如接口,在Go 1.20之前被排除在外)。
确实,在Go语言规范中,比较运算符包括顺序运算符(<
, >
, <=
, >=
)。这种术语的选择可能让你感到困惑。然而,规范也对此进行了澄清:
> 相等运算符==
和!=
适用于可比较的操作数。顺序运算符<
, <=
, >
, 和 >=
适用于有序的操作数。
Go 1.21
可以使用标准库中的cmp.Ordered
。
> 新的cmp包定义了类型约束Ordered和两个新的通用函数Less和Compare,它们对有序类型非常有用。
Go 1.18 到 1.20
在Go 1.18中,支持>
和<
等顺序运算符的可用约束是constraints.Ordered
<sup>1</sup>:
type Ordered interface {
Integer | Float | ~string
}
<hr>
<sup>1:请注意,golang.org/x/exp
包是实验性的。它的内容不能保证与新的Go版本向后兼容,但您可以随时将所需的定义复制粘贴到自己的代码中。</sup>
英文:
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.
Go 1.21
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.
Go 1.18 to 1.20
In Go 1.18 the available constraint that supports the order operators such as >
and <
is constraints.Ordered
<sup>1</sup>:
type Ordered interface {
Integer | Float | ~string
}
<hr>
<sup>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</sup>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论