Other ways of verifying reflect.Type for int and float64

后端 未结 2 700
梦如初夏
梦如初夏 2021-02-11 03:00

In golang, a number in JSON message is always parsed into float64. In order to detect if it is actually integer, I am using reflect.TypeOf() to check its type. Unfo

相关标签:
2条回答
  • 2021-02-11 03:46

    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.

    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 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).

    0 讨论(0)
  • 2021-02-11 03:58

    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. So if myVar is a parsed JSON number, it will always have type of float64 instead of 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. Take a look at 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
    }
    
    0 讨论(0)
提交回复
热议问题