2017-01-06 17 views
8

Nie rozumiem, dlaczego pierwszym wynikiem jest fałsz, a druga jest prawdą.Interfejs i porównanie liczb całkowitych w golang

Każda pomoc zostanie doceniona.

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 

Spróbuj tutaj Go playground

Odpowiedz

10

Ponieważ 0 jest pozbawionym typu stała którego Domyślnym typem jest int nie uint64, a kiedy robi porównania z interfejsem, rzecz porównujesz, musi być zarówno sam typ i taką samą wartość, aby można je było uznać za równe.

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

Równość operatory == i! = Stosuje się do argumentów, które są porównywalne. Operatory porządkowania <, < =,> i> = odnoszą się do uporządkowanych argumentów. Warunki te i wyniki porównań są zdefiniowane następująco:

Wartość x typu bez interfejsu typu X i wartość t interfejsu typu T są porównywalne, gdy wartości typu X są porównywalne, a X implementuje T. Są one równy, jeśli dynamiczny typ t jest identyczny z wartością dynamiczną X i t jest równy x.

+0

Dlaczego można użyć asercji typu, takiej jak 'i. (Uint64) == 0'? Czy kompilator zakłada również, że '0' jest' uint64'? https://play.golang.org/p/YT-pZCdI27 – Ngenator

+2

Po wykonaniu asercji typu nie porównujesz już interfejsu z wartością, porównujesz wartość z wartością, więc tracisz wymaganie typy dynamiczne muszą być równe. – dave

+1

Technicznie '0' nie jest' int', jest to ["stała bez typu"] (https://golang.org/ref/spec#Constants), która jest konwertowana na domyślny typ 'int' z powodu umieszczenia w ekspresja. – JimB