在golang中,我们可以通过 x.(type) 加 switch case的形式来对一个any类型的变量进行类型的判断和处理。这里的 x代表的是你要进行类型判断的any类型的变量, .(type)是一个固定写法, 和这个语法模式长得相似的有 类型断言 x.(类型/接口) , 不过他们的用法和结果可完全不一样哦,大家要分清楚了。 另外我们还可以通过反射对象的rv.Kind()方法然后使用reflect.Xxx类型来进行any类型的数据类型case, 然后在使用反射对象rv中的对应类型的大方法,如String, Int, Uint, Float, Bool方法获取any类型数据当前实际的数据类型的值。 如 intv := rv.Int() 获取reflect.Value反射中的对象对应的int类型的值。
废话不多说,直接上示例。
x.(type) + switch case使用示例
// x.(type) + switch case使用示例
// 将any类型的x转换为string类型
func ToString(x interface{}) string {
switch val := x.(type) {
case int:
return strconv.Itoa(val)
case uint: // 注意这里的分支选择,如果要在里面使用强转,则这里只能有1个类型,不能是多个类型(如 case uint,uint8: 这样就不能使用类型强转)
// 因为从这个分支进来,就可以明确了val是uint类型,这时就可以使用同大类型的强制转换了,即 uint64(val) 强转val为uint64类型
return strconv.FormatUint(uint64(val), 10)
case string:
return val // 注意 这里的val就是 string类型的数据了
case float64:
// 这里的FormatFloat格式化,第一个参数val是float64类型的要格式化的数据,第二个参数就是我们的格式化符号,可选'e', 'E', 'f', 'g', 'G', 'x', and 'X',第三个是小数点的长度。-1表示不限制,第4个参数是数据的位数(32或者64)
return strconv.FormatFloat(val, 'f', -1, 64)
case time.Time://时间类型
// Time类型的零值判断通过IsZero方法来完成,因为他的零值是很长的一个字符串“January 1, year 1, 00:00:00 UTC”
if val.IsZero() {
return ""
}
return val.String()
default:
// 不写了,直接来个大杀器,使用fmt.Sprintf转换为string
return fmt.Sprintf("%v", val)
}
}
上面示例中的case的类型,可以是任意的go支持的类型,包括自定义的类型或者结构体都可以作为case条件来进行判断,上面的 time.Time 他就是一个结构体,只不过是系统内置的而已,你可以根据不同的类型做不同的处理。
通过 v := x.(type) 类型判断后,这里的 x 经过switch case后的 v 就是具体的类型的值。
如, 转换 any类型的value 到 string 示例代码
func AnyToStr(value interface{}) string {
if value == nil {
return ""
}
// 先使用 type switch来判断数据类型
switch vt := value.(type) {
case string:
return vt
case []byte:
return string(vt)
}
}
内存图示
使用reflect.Value反射对象的Kind()方法获取any类型变量的具体的值示例
下面的示例是使用放射获取reflect.Value对象后再使用 switch x.Kind()方法 加 case reflect.Xxx类型后 在调用大类型方法(如String, Int , Uint, Float, Bool等)获取any对应的实际类型的值示例
// 将any类型的数据转换为string字符串类型
func AnyToStr(value interface{}) string {
// Indirect方法兼容指针或者值
vrt := reflect.Indirect(reflect.ValueOf(value))
switch vrt.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return strconv.FormatInt(vrt.Int(), 10)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return strconv.FormatUint(vrt.Uint(), 10)
case reflect.Float64:
return strconv.FormatFloat(vrt.Float(), 'g', -1, 64)
case reflect.Float32:
return strconv.FormatFloat(vrt.Float(), 'g', -1, 32)
case reflect.Bool:
return strconv.FormatBool(vrt.Bool())
default:
// 使用%v 格式化为字符串返回
return fmt.Sprintf("%v", vrt.Interface())
}
}