比较float64值和常量

时间:2017-11-02 14:17:51

标签: go floating-point comparison constants

当你使用interface {}和它的类型检测时,我发现了一个不清楚和有点奇怪的事情,比较了JSON的解组值。     包主要

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\n",c == 200) /// comparison with float64 is ok

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

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

输出:

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)

如您所见,2个变量看起来相同,具有相同的类型和值,但比较结果不同。

有人可以帮助我理解为什么吗?

这是一个游乐场 - https://play.golang.org/p/KaB_UwDK2N

1 个答案:

答案 0 :(得分:3)

200是一个无类型常量。 spec says this about untyped constants

  

非类型化常量具有默认类型,该类型是在需要键入值的上下文中隐式转换常量的类型,例如,在短变量声明中,例如i:= 0,其中没有显式类型。无类型常量的默认类型分别是bool,rune,int,float64,complex128或string,具体取决于它是布尔值,符文,整数,浮点数,复数还是字符串常量。

表达式t["code"] == 200的计算结果为false,因为无类型200会隐式转换为默认int,以便与interface{}进行比较。 float64中的interface{}不等于int 200。

其他比较返回true,因为不需要隐式类型转换为默认类型。

表达式t["code"] == 200.0的计算结果为true,因为200.0float64常量。

比较结果与JSON解码无关。请参阅https://play.golang.org/p/4BXMI0SnoL