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

adi*_*571 1 interface go

例如:

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

Run Code Online (Sandbox Code Playgroud)

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

cannot compare a > b (operator > not defined for interface{})compiler

Run Code Online (Sandbox Code Playgroud)

bla*_*een 7

tl;dr 是的,这是可能的,但并非总是如此

来自关于比较运算符的 Go 规范(强调我的)

相等运算符==!=适用于可比较的操作数。排序运算符<<=>>=适用于已排序的操作数。这些术语和比较结果的定义如下:

进而:

接口值具有可比性。如果两个接口值具有相同的动态类型和相等的动态值,或者两者的值为 nil,则它们相等。

因此接口值没有排序,因此您使用运算符的示例>无法编译。

这反而有效:

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")
}
Run Code Online (Sandbox Code Playgroud)

作为附加说明,请考虑当接口值不可比较时,编译的代码可能仍然会发生混乱。再次引用Go 规范

如果该类型的值不可比较,则具有相同动态类型的两个接口值的比较会导致运行时恐慌。此行为不仅适用于直接接口值比较,还适用于将接口值或结构的数组与接口值字段进行比较时。

切片、映射和函数值不可比较

这意味着以下代码可以编译但在运行时会发生恐慌:

compare([]int{12}, []int{12}) // panic: runtime error: comparing uncomparable type []int
Run Code Online (Sandbox Code Playgroud)

你可以在Go Play上乱用这段代码