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