go之value、Type小记
更新日期:
go语言里面没有类似template的东西,也没有函数重载和函数默认参数,所以要实现一些功能时需要借助interface{}和reflect,下面记录一些用法。
1.interface{} 实现要接纳多种类型的参数,好似template
interface{}能够接纳所以类型,但是用的时候要判断实际的类型进行不同的处理,一般用switch .(type)来判断,例如:1
2
3
4
5
6
7
8
9
10
11
12func Test(i interface{}) {
switch v := i.(type) {
case int:
fmt.Println("int", v)
case *int:
fmt.Println("*int", v)
case []byte:
fmt.Println("[]byte", v)
default:
fmt.Println("unkown")
}
}
也可以利用refect.TypeOf来判断,例如:1
2
3
4
5
6
7
8func Test1(i interface{}) {
ityp := reflect.TypeOf(i)
if ityp.Kind() == reflect.Int {
fmt.Println("int", i.(int))
} else if ityp.Kind() == reflect.Ptr && ityp.Elem().Kind() == reflect.Int {
fmt.Println("*int", i.(*int))
}
}
2.根据Type创建新值1
2ityp := reflect.TypeOf(i)
val := reflect.New(ityp ).Interface()
3.获取Struct成员地址1
2
3i:=&Struct{XXX}
vals:=reflect.ValueOf(i).Elem()
ptr:=vals.FieldByName("x").Addr().Interface()
4.遍历interface{}参数slice1
2
3
4
5
6
7
8
9
10
11
12
13
14func InterfaceSlice(slice inteface{}) []interface{} {
s := reflect.ValueOf(slice)
if s.Kind() != reflect.Slice {
panic("InterfaceSlice() given a non-slice type")
}
ret := make([]interface{}, s.Len())
for i:=0; i<s.Len(); i++ {
ret[i] = s.Index(i).Interface()
}
return ret
}
5.赋值1
2
3
4
5
6
7
8func Test(i interface{}, j interface{}) {
iv := reflect.ValueOf(i)
jv := reflect.ValueOf(j)
if iv.Kind() != reflect.Ptr || jv.Kind() != reflect.Ptr {
panic("should be a pointer")
}
iv.Elem().Set(jv.Elem())
}
6.TypeOf才能获取interface的实际类型1
2
3
4
5
6
7
8
9var in interface{}
in = person{5, "e", 10}
fmt.Println(reflect.TypeOf(in), reflect.TypeOf(&in), reflect.TypeOf(&in).Elem())
fmt.Println(reflect.ValueOf(&in).Type(), reflect.ValueOf(&in).Elem().Type())
fmt.Println(reflect.TypeOf(reflect.ValueOf(&in).Interface()), reflect.TypeOf(reflect.ValueOf(&in).Elem().Interface()))
输出:
person *interface{} interface {}
*interface{} interface {}
*interface{} person
7.reflect.Zero1
2
3
4per := &person{5, "e", 10}
val := reflect.ValueOf(per).Elem()
val.Set(reflect.Zero(val.Type()))
fmt.Println(*per)
8.杂
- i:=[]interface{}如果想获得i里面元素的类型,reflect.TypeOf(i).Elem()这样是不行的,它会返回interface{},需使用reflect.TypeOf(reflect.ValueOf(i).Index(0).Interface())
- // Elem returns a type’s element type.
// It panics if the type’s Kind is not Array, Chan, Map, Ptr, or Slice.
Elem() Type - // Elem returns the value that the interface v contains
// or that the pointer v points to.
// It panics if v’s Kind is not Interface or Ptr.
// It returns the zero Value if v is nil.
Elem() Value