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