空接口可以存储任意类型的数据,当需要判断到底是何种类型时,可以使用以下方法。
1 直接断言
比如我们收到一个类型为interface{}的变量unknown,可以通过如下代码直接断言是否为string类型:
val, ok := unknow.(string)
如果返回ok为true,则变量unknown为string类型,同时返回一个val存储string类型的值。
如果我们确定unknown为string类型,也可以不返回ok变量,直接强转获取其值:
val := unknow.(string)
但是使用这种方法有一定的风险,如果不是string类型,会发生panic:
panic: interface conversion: interface {} is int, not string
2 反射
反射位于relfect包,获取类型使用reflect.TypeOf,获取值使用reflect.ValueOf,具体使用方法:
retType = reflect.TypeOf(unknow)
val = reflect.ValueOf(unknow)
3 type关键字判断
该方法必须适用于switch case中,通过不同的case来进行不同的处理。
switch unknow.(type){
case string:
//string类型
case int:
//int类型
}
举例说明
该例子分别用了上述列举的各种方法来对一个字符串进行类型判断及取值。
package main
import (
"fmt"
"reflect"
)
func main(){
var str interface{} = "abc"
retType,val := interfaceAssert1(str)
fmt.Printf("type:%v, value:%v\n", retType, val)
retType2,val2 := interfaceAssert2(str)
fmt.Printf("type:%v, value:%v\n", retType2, val2)
retType3 := interfaceAssert3(str)
fmt.Printf("type:%v\n", retType3)
}
//直接断言
func interfaceAssert1(unknow interface{})(retType string, val interface{}){
val, ok := unknow.(string)
if ok{
return "string", val
}else{
return "not string", nil
}
}
//反射
func interfaceAssert2(unknow interface{})(retType reflect.Type, val reflect.Value){
retType = reflect.TypeOf(unknow)
val = reflect.ValueOf(unknow)
return retType,val
}
//type关键字
func interfaceAssert3(unknow interface{})(retType string){
switch unknow.(type){
case string:
return "string"
case int:
return "int"
default:
return "other type"
}
}