
在 go 中,json 解析后的数字默认为 float64,若需区分整数与浮点数,应优先使用 reflect.kind() 而非创建占位值(如 0 或 0.0)来获取 reflect.type 进行比较,因其更安全、高效且语义清晰。
在 go 中,json 解析后的数字默认为 float64,若需区分整数与浮点数,应优先使用 reflect.kind() 而非创建占位值(如 0 或 0.0)来获取 reflect.type 进行比较,因其更安全、高效且语义清晰。
Go 的 reflect 包提供了 Kind() 方法,用于获取类型的底层类别(underlying kind),它返回一个 reflect.Kind 类型的常量(如 reflect.Int、reflect.Float64 等)。相比通过 reflect.TypeOf(0) 或 reflect.TypeOf(0.0) 创建临时值再比对 reflect.Type 实例,Kind() 方式无需构造运行时对象,避免了内存分配和指针比较风险,也更符合类型检查的本意——我们真正关心的是“这是哪种基本类型”,而非“是否与某个特定实例的 Type 完全相同”。
以下为推荐用法:
myType := reflect.TypeOf(myVar)
switch myType.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
fmt.Println("这是一个有符号整数类型")
case reflect.Float32, reflect.Float64:
fmt.Println("这是一个浮点数类型")
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
fmt.Println("这是一个无符号整数类型")
default:
fmt.Printf("其他类型:%v\n", myType.Kind())
}
你也可以直接从 reflect.Value 出发(例如解析 JSON 后已得 interface{} 值):
v := reflect.ValueOf(myVar)
switch v.Kind() {
case reflect.Int, reflect.Int64:
// 注意:Int64 是 Kind,但 int 和 int64 的 Kind 都是 reflect.Int
fmt.Println("整数值")
case reflect.Float64:
fmt.Println("浮点数值")
}
⚠️ 注意事项:
- reflect.Type.Kind() 和 reflect.Value.Kind() 返回值一致,二者可互换使用,选择取决于你当前持有的是类型描述(Type)还是值包装(Value);
- Kind() 判断的是底层类型类别,不区分具体命名类型(例如 type MyInt int 的 Kind 仍是 reflect.Int),若需严格匹配命名类型(如 int 而非 MyInt),才需用 Type == reflect.TypeOf(int(0)),但此类场景较少;
- 对于 JSON 反序列化后的 interface{} 值,建议先用 json.Unmarshal 或 json.RawMessage 控制解析粒度,或结合 fmt.Sprintf("%v", v) + 正则校验小数点,作为 reflect 方案的轻量补充。
综上,使用 Kind() 是判断基础数值类型最简洁、健壮且符合 Go 反射设计哲学的方式。











