gpt4 book ai didi

go - 无效操作 : a > b (operator > not defined on interface)

转载 作者:行者123 更新时间:2023-12-01 20:23:16 25 4
gpt4 key购买 nike

是否可以在 Go 中比较两个接口(interface)值?

例如:

func compare(a interface{}, b interface{}) {
if a > b {
fmt.Printf("%v is bigger than %v", a, b)
}
}

但最后,我得到了编译器错误:

invalid operation: a > b (operator > not defined on interface)

Playground :https://play.golang.org/p/iyfw3u6-VeY

最佳答案

您可以比较接口(interface)值的相等性,但不能比较顺序。

Go 规范可能听起来有点困惑,因为相关段落称为 Comparison operators但随后继续区分相等比较和顺序比较(强调我的):

The equality operators == and != apply to operands that are comparable. The ordering operators <, <=, >, and >= apply to operands that are ordered. These terms and the result of the comparisons are defined as follows:

然后:

  • Integer values are comparable and ordered, in the usual way.

  • [...]

  • Interface values are comparable. Two interface values are equal if they have identical dynamic types and equal dynamic values or if both have value nil.

关于接口(interface)的观点没有提到顺序,因此您可以推断接口(interface)值是无序的。因此,您的示例使用运算符 >不编译。

这个,使用相等运算符,而是有效的:

type A struct {
val int8
}

func main() {
var x, y int = 1, 2

compare(x, y) // a and b are not equal

compare(nil, nil) // a and b are equal

compare(A{12}, A{12}) // a and b are equal

compare(A{12}, A{45}) // a and b are not equal
}

func compare(a interface{}, b interface{}) {
if a == b {
fmt.Println("a and b are equal")
return
}
fmt.Println("a and b are not equal")
}

作为附加说明,考虑到当接口(interface)值不可等式比较时,编译的代码可能仍然会出现 panic。引用 Go specs again :

A comparison of two interface values with identical dynamic types causes a run-time panic if values of that type are not comparable. This behavior applies not only to direct interface value comparisons but also when comparing arrays of interface values or structs with interface-valued fields.

Slice, map, and function values are not comparable.

这意味着以下代码可以编译但在运行时会出现错误:

compare([]int{12}, []int{12}) // panic: runtime error: comparing uncomparable type []int

警告:上面的段落指定了“相同的动态类型”,因此如果您比较两个不同类型的接口(interface),即使其中一个或两者不可比较,比较将不会 panic 并返回false:

    var a interface{} = 500             // numerical: comparable
var b interface{} = []string{"foo"} // slice: not comparable
fmt.Println(a == b) // false

参见 Go Playground 中的代码


作为替代方案,使用 Go 1.18 和泛型,您可以显式地将参数类型限制为可排序类型,然后您将能够在函数体中使用排序运算符:

func compare[T constraints.Ordered](a, b T) {
// works
if a > b {
fmt.Printf("%v is bigger than %v", a, b)
}
}

关于go - 无效操作 : a > b (operator > not defined on interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62944464/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com