比较float64值和常量

I found an unclear and a bit strange thing in comparison of unmarshaled values of JSON when you using interface{} and it's type detection. package main

import (
    "fmt"
    "os"
    "encoding/json"
    "reflect"
)

type Message struct {
    Code int `json:"code"`
}

func main() {
    var jsons []byte = []byte(`{ "code":200 }`)
    var t = make(map[string]interface{})
    e:= json.Unmarshal(jsons, &t)
    if e != nil {
        fmt.Printf("Unmarshal error: %v", e)
        os.Exit(1)
    }

    var c float64 = 200
    fmt.Printf("Comparison with manually defined float64: %t
",c == 200) /// comparison with float64 is ok

    fmt.Printf("Type of 'code' value: %s
", reflect.TypeOf(t["code"])) // here is a float64 type
    fmt.Printf("Comparison without type assertion: %t
", t["code"] == 200) // returning false
    fmt.Printf("Comparison with type assertion: %t
", t["code"].(float64) == 200) // returning true

    fmt.Printf("
%", t["code"])
    fmt.Printf("
%", t["code"].(float64))
    }

Output:

Comparison with manually defined float64: true
Type of 'code' value: float64
Comparison without type assertion: false
Comparison with type assertion: true

%!(NOVERB)%!(EXTRA float64=200)
%!(NOVERB)%!(EXTRA float64=200)

As you can see, that 2 variables look same, has same type and value, but the result of a comparison is different.

Can somebody help me to understand why?

Here is a playground - https://play.golang.org/p/KaB_UwDK2N

The value 200 is an untyped constant. The spec says this about untyped constants:

An untyped constant has a default type which is the type to which the constant is implicitly converted in contexts where a typed value is required, for instance, in a short variable declaration such as i := 0 where there is no explicit type. The default type of an untyped constant is bool, rune, int, float64, complex128 or string respectively, depending on whether it is a boolean, rune, integer, floating-point, complex, or string constant.

The expression t["code"] == 200 evaluates to false because the untyped 200 is implicitly converted to the default int for the comparison with interface{}. The float64 in the interface{} is not equal to the int 200.

The other comparisons return true because implicit type conversions to the default type are not needed.

The expression t["code"] == 200.0 evaluates to true because 200.0 is a float64 constant.

The comparison results are unrelated to JSON decoding. See https://play.golang.org/p/4BXMI0SnoL.