在 Golang 中,接口和整数的比较问题

10
我不明白为什么第一个结果是假的,而第二个结果是真的。
任何帮助将不胜感激。
func main() {
    var i interface{}

    i = uint64(0)
    fmt.Println("[1] ", reflect.TypeOf(i), i == 0)

    i = 0
    fmt.Println("[2] ", reflect.TypeOf(i), i == 0)

    var n uint64 = 32
    fmt.Println("[3] ", reflect.TypeOf(n), n == 32) 
}

// result
// [1]  uint64 false
// [2]  int true
// [3]  uint64 true

在这里尝试一下:Go playground

1个回答

11
因为0是一个未指定类型的常量,其默认类型为int而不是uint64。在与接口进行比较时,被比较的对象必须既是相同的类型又是相同的值才能被视为相等。
参考链接:https://golang.org/ref/spec#Comparison_operators 引用如下:
等号(==)和不等号(!=)运算符适用于可比较的操作数。小于号(<)、小于等于号(<=)、大于号(>)和大于等于号(>=)运算符适用于有序的操作数。这些术语及比较结果的定义如下:
非接口类型X的值x和接口类型T的值t是可比较的,当且仅当类型X的值是可比较的并且X实现了T。当t的动态类型与X相同时且t的动态值等于x时,它们是相等的。

为什么可以使用类型断言,例如i.(uint64) == 0?编译器是否也假定0uint64类型的?https://play.golang.org/p/YT-pZCdI27 - Ngenator
2
一旦进行类型断言,您不再比较接口与值,而是比较值与值,因此失去了它们动态类型需要相等的要求。 - dave
1
从技术上讲,0 不是一个 int,它是一个 "未命名常量",由于其在表达式中的位置,因此被转换为默认类型 int - JimB
@JimB 这是真的,我是指在比较时,但我已经更新了我的答案以更加精确。 - dave

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接