简体   繁体   English

验证reflect.Type的其他方法int和float64

[英]Other ways of verifying reflect.Type for int and float64

In golang, a number in JSON message is always parsed into float64. 在golang中,始终将JSON消息中的数字解析为float64。 In order to detect if it is actually integer, I am using reflect.TypeOf() to check its type. 为了检测它是否实际上是整数,我使用reflect.TypeOf()检查其类型。 Unfortunately there is no constant that represents reflect.Type . 不幸的是,没有常数代表reflect.Type

intType := reflect.TypeOf(0)
floatType := reflect.TypeOf(0.0)
myType := reflect.TypeOf(myVar)
if myType == intType {
    // do something
}

Is there more elegant solution instead of using 0 or 0.0 to get reflect.Type ? 有没有更优雅的解决方案,而不是使用0或0.0来获取reflect.Type

You may also use the Value.Kind() or Type.Kind() method whose possible values are listed as constants in the reflect package, at the doc of the Kind type. 您还可以在Kind类型的doc上使用Value.Kind()Type.Kind()方法,其可能的值在reflect包中作为常量列出。

myType := reflect.TypeOf(myVar)
if k := myType.Kind(); k == reflect.Int {
    fmt.Println("It's of type int")
} else if k == reflect.Float64 {
    fmt.Println("It's of type float64")
}

You can also use it in a switch : 您也可以在switch使用它:

switch myType.Kind() {
case reflect.Int:
    fmt.Println("int")
case reflect.Float64:
    fmt.Println("float64")
default:
    fmt.Println("Some other type")
}

Note that both reflect.Type and reflect.Value has a Kind() method, so you can use it if you start with reflect.ValueOf(myVar) and also if you start with reflect.TypeOf(myVar) . 请注意, reflect.Typereflect.Value都具有Kind()方法,因此,如果您以reflect.ValueOf(myVar)开头,也可以以reflect.TypeOf(myVar)开头,则可以使用它。

To check if interface is of a specific type you can use type assertion with two return values, the second return value is a boolean indicating if the variable is of the type specified. 要检查接口是否为特定类型,可以将类型断言与两个返回值一起使用,第二个返回值是一个布尔值,指示变量是否为指定的类型。 And unlike with a single return value, it will not panic if the variable is of a wrong type. 并且与单个返回值不同,如果变量的类型错误,它不会惊慌。

if v, ok := myVar.(int); ok {
    // type assertion succeeded and v is myVar asserted to type int
} else {
    // type assertion failed, myVar wasn't an int
}

If there's more types that you need to check then using a type switch is a good idea: 如果需要检查更多类型,那么使用类型开关是一个好主意:

switch v := myVar.(type) {
case int:
    // v has type int
case float64:
    // v has type float64
default:
    // myVar was something other than int or float64
}

Note however that neither of these actually solve your problem, because like you say, numbers in JSON documents are always parsed into float64s. 但是请注意,这两种方法都不能真正解决您的问题,因为就像您说的那样,JSON文档中的数字始终会解析为float64s。 So if myVar is a parsed JSON number, it will always have type of float64 instead of int. 因此,如果myVar是已解析的JSON数字,它将始终具有float64类型而不是int类型。

To solve this, I suggest you use the UseNumber() method of the json.Decoder, which causes the decoder to parse numbers as type Number, instead of float64. 为了解决这个问题,我建议您使用json.Decoder的UseNumber()方法,该方法使解码器将数字解析为Number类型,而不是float64。 Take a look at https://golang.org/pkg/encoding/json/#Number 看看https://golang.org/pkg/encoding/json/#Number

// Assume myVar is a value decoded with json.Decoder with UseNumber() called

if n, ok := myVar.(json.Number); ok {
    // myVar was a number, let's see if its float64 or int64
    // Check for int64 first because floats can be parsed as ints but not the other way around
    if v, err := n.Int64(); err != nil {
        // The number was an integer, v has type of int64
    }
    if v, err := n.Float64(); err != nil {
        // The number was a float, v has type of float64
    }
} else {
    // myVar wasn't a number at all
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM