2017-01-06 3 views
8

Я не понимаю, почему первый результат является ложным, а второй - истиной.интерфейс и целочисленное сравнение в golang

Любая помощь будет оценена по достоинству.

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

ответ

10

Поскольку 0 является нетипизированная константа, тип по умолчанию int, не uint64, и при выполнении сравнения с интерфейсом, то, что вы сравниваете, должен быть и тот же тип и такое же значение для них считается равным.

https://golang.org/ref/spec#Comparison_operators

Равенство операторов == и! = Применимы к операндам, которые сопоставимы. Операторы упорядочения <, < =,>, и> = применяются к упорядоченным операндам. Эти термины и результат сравнений определяются следующим образом:

Значение x типа неинтерфейса X и значение t типа интерфейса T сопоставимы, когда значения типа X сопоставимы, а X реализует T. Они являются равно, если динамический тип t идентичен X, а динамическое значение t равно x.

+0

Почему вы можете использовать утверждение типа, такое как 'i. (Uint64) == 0'? Представляет ли компилятор '0' также' uint64'? https://play.golang.org/p/YT-pZCdI27 – Ngenator

+2

Как только вы выполните утверждение типа, вы больше не сравниваете интерфейс со значением, вы сравниваете значение со значением, поэтому вы теряете требование своих динамические типы должны быть равными. – dave

+1

Технически '0' не является' int', это ["нетипированная константа"] (https://golang.org/ref/spec#Constants), которая преобразуется в тип 'int' по умолчанию из-за его размещения в выражение. – JimB

Смежные вопросы