[golang]golang reflect详细用法整理

本博客原创博文版权所有 @[email protected]
仅供交流学习使用用于商业用途请联系原作者 
转载请注明出处:http://blog.sina.com.cn/ally2014
 
最近在尝试用Go写一些东西,发现Go不支持泛型确实是一件比较蛋疼的事,同样功能的一个类,只有底层数据结构有一点点差异,需要实现N遍。特别像我这种在C++世界挣扎也纠结了很多年,用惯了模板编程思想的程序猿。好在Golang提供了reflect机制,可以在一定程度上满足对泛型编程的一些需求。
想实现的一些需求:
1.通过类型字符串动态创建类型对象
2.动态的调用一些预定义函数,而不需要依赖实现该函数的package
3.实现一些通用的数据结构,比如像C++ STL那样的泛型容器
4.一些特定类型的检查和操作 如chan Type,[]Type
5...
 
//---------------------------------以下是用reflect实现一些类型无关的泛型编程示例
//new object same the type as sample
func New(sample interface{}) interface{} {
      t :=reflect.ValueOf(sample).Type()
      v :=reflect.New(t).Interface()
      returnv
}
//---------------------------------check type of aninterface
func CheckType(val interface{}, kind reflect.Kind) bool {
      v :=reflect.ValueOf(val)
      return kind== v.Kind()
}
//---------------------------------if _func is not a functionor para num and type not match,it will cause panic
func Call(_func interface{}, params ...interface{}) (result[]interface{}, err error) {
      f :=reflect.ValueOf(_func)
      iflen(params) != f.Type().NumIn() {
              ss := fmt.Sprintf("The number of params is not adapted.%s",f.String())
              panic(ss)
              return
      }
      var in[]reflect.Value
      iflen(params) > 0 { //prepare in paras
              in = make([]reflect.Value, len(params))
              for k, param := range params {
                      in[k] = reflect.ValueOf(param)
              }
      }
      out :=f.Call(in)
      if len(out)> 0 { //prepare out paras
              result = make([]interface{}, len(out), len(out))
              for i, v := range out {
                      result[i] = v.Interface()
              }
      }
      return
}
//---------------------------------if ch is not channel,itwill panic
func ChanRecv(ch interface{}) (r interface{}) {
      v :=reflect.ValueOf(ch)
      if x, ok :=v.Recv(); ok {
              r = x.Interface()
      }
      return
}
//---------------------------------reflect fields of astruct
func reflect_struct_info(it interface{}) {
      t :=reflect.TypeOf(it)
      fmt.Printf("interface info:%s %s %s %s\n", t.Kind(), t.PkgPath(),t.Name(), t)
      if t.Kind()== reflect.Ptr { //if it is pointer, get it element type
              tt := t.Elem()
              if t.Kind() == reflect.Interface {
                      fmt.Println(t.PkgPath(), t.Name())
                      for i := 0; i < tt.NumMethod(); i++ {
                              f := tt.Method(i)
                              fmt.Println(i, f)
                      }
              }
      }
      v :=reflect.ValueOf(it)
      k :=t.Kind()
      if k ==reflect.Ptr {
              v = v.Elem() //指针转换为对应的结构
              t = v.Type()
              k = t.Kind()
      }
      fmt.Printf("value type info:%s %s %s\n", t.Kind(), t.PkgPath(),t.Name())
      if k ==reflect.Struct { //反射结构体成员信息
              for i := 0; i < t.NumField(); i++ {
                      f := t.Field(i)
                      fmt.Printf("%s %v\n", i, f)
              }
              for i := 0; i < t.NumMethod(); i++ {
                      f := t.Method(i)
                      fmt.Println(i, f)
              }
              fmt.Printf("Fileds:\n")
              f := v.MethodByName("func_name")
              if f.IsValid() { //执行某个成员函数
                      arg := []reflect.Value{reflect.ValueOf(int(2))}
                      f.Call(arg)
              }
              for i := 0; i < v.NumField(); i++ {
                      f := v.Field(i)
                      if !f.CanInterface() {
                              fmt.Printf("%d:[%s] %v\n", i, t.Field(i), f.Type())
                              continue
                      }
                      val := f.Interface()
                      fmt.Printf("%d:[%s] %v %v\n", i, t.Field(i), f.Type(), val)
              }
              fmt.Printf("Methods:\n")
              for i := 0; i < v.NumMethod(); i++ {
                      m := v.Method(i)
                      fmt.Printf("%d:[%v] %v\n", i, t.Method(i), m)
              }
      }
}
//---------------------------------以下是本人对goreflect的一些理解不正之处欢迎指正
Go reflect对go的底层数据结构抽象大概可以定义成如下:
type reflectKind int
type reflectStructField struct {
      reflectValue
      Name      string
      PkgPathstring
      Type          reflectType// field type
      Tag            StructTag // field tag string
      Offset      uintptr    // offset withinstruct, in bytes
      Index        []int        // index sequence for Type.FieldByIndex
      Anonymousbool          // is an embedded field
}
type reflectMethod strut{
      Name      string
      PkgPathstring
      Type  reflectType  // methodtype
      Func  Value // func with receiver as firstargument
      Indexint    // index forType.Method
}
//any go type can abstact as a reflectType
type reflectType struct {
      Kind      reflectKind
      Name      string
      PkgPathstring
      Fields  []reflectType
      Methods[]reflectMethod
}
//every go value(with any go type) can abstact as areflectValue
type reflectValue struct {
      Type    reflectType
      Value  unsafePointer
      Fields[]reflectStructField
      SpecificValueOpers()
}
//----------------------------------------------an imagined type inGO
type GoType struct {
      reflectType
      reflectValue
}
//---------------------------------------------- 
...未完待续
 
附:package reflect包类型函数说明
func Copy(dst, src Value) int
func DeepEqual(a1, a2 interface{}) bool
func Select(cases []SelectCase) (chosen int, recv Value, recvOKbool)
type ChanDir
func (d ChanDir) String() string
type Kind
      const(
              Invalid Kind = iota
              Bool
              Int
              Int8
              Int16
              Int32
              Int64
              Uint
              Uint8
              Uint16
              Uint32
              Uint64
              Uintptr
              Float32
              Float64
              Complex64
              Complex128
              Array
              Chan
              Func
              Interface
              Map
              Ptr
              Slice
              String
              Struct
              UnsafePointer
      )
      func (kKind) String() string
type Method
type SelectCase
type SelectDir
type SliceHeader
type StringHeader
type StructField
type StructTag
func (tag StructTag) Get(key string) string
type Type
      funcChanOf(dir ChanDir, t Type) Type
      funcMapOf(key, elem Type) Type
      func PtrTo(tType) Type
      funcSliceOf(t Type) Type
      funcTypeOf(i interface{}) Type
type Value
      funcAppend(s Value, x ...Value) Value
      funcAppendSlice(s, t Value) Value
      funcIndirect(v Value) Value
      funcMakeChan(typ Type, buffer int) Value
      funcMakeFunc(typ Type, fn func(args []Value) (results []Value))Value
      funcMakeMap(typ Type) Value
      funcMakeSlice(typ Type, len, cap int) Value
      func New(typType) Value
      funcNewAt(typ Type, p unsafe.Pointer) Value
      funcValueOf(i interface{}) Value
      funcZero(typ Type) Value
      func (vValue) Addr() Value
      func (vValue) Bool() bool
      func (vValue) Bytes() []byte
      func (vValue) Call(in []Value) []Value
      func (vValue) CallSlice(in []Value) []Value
      func (vValue) CanAddr() bool
      func (vValue) CanInterface() bool
      func (vValue) CanSet() bool
      func (vValue) Cap() int
      func (vValue) Close()
      func (vValue) Complex() complex128
      func (vValue) Convert(t Type) Value
      func (vValue) Elem() Value
      func (vValue) Field(i int) Value
      func (vValue) FieldByIndex(index []int) Value
      func (vValue) FieldByName(name string) Value
      func (vValue) FieldByNameFunc(match func(string) bool) Value
      func (vValue) Float() float64
      func (vValue) Index(i int) Value
      func (vValue) Int() int64
      func (vValue) Interface() (i interface{})
      func (vValue) InterfaceData() [2]uintptr
      func (vValue) IsNil() bool
      func (vValue) IsValid() bool
      func (vValue) Kind() Kind
      func (vValue) Len() int
      func (vValue) MapIndex(key Value) Value
      func (vValue) MapKeys() []Value
      func (vValue) Method(i int) Value
      func (vValue) MethodByName(name string) Value
      func (vValue) NumField() int
      func (vValue) NumMethod() int
      func (vValue) OverflowComplex(x complex128) bool
      func (vValue) OverflowFloat(x float64) bool
      func (vValue) OverflowInt(x int64) bool
      func (vValue) OverflowUint(x uint64) bool
      func (vValue) Pointer() uintptr
      func (vValue) Recv() (x Value, ok bool)
      func (vValue) Send(x Value)
      func (vValue) Set(x Value)
      func (vValue) SetBool(x bool)
      func (vValue) SetBytes(x []byte)
      func (vValue) SetComplex(x complex128)
      func (vValue) SetFloat(x float64)
      func (vValue) SetInt(x int64)
      func (vValue) SetLen(n int)
      func (vValue) SetMapIndex(key, val Value)
      func (vValue) SetPointer(x unsafe.Pointer)
      func (vValue) SetString(x string)
      func (vValue) SetUint(x uint64)
      func (vValue) Slice(beg, end int) Value
      func (vValue) String() string
      func (vValue) TryRecv() (x Value, ok bool)
      func (vValue) TrySend(x Value) bool
      func (vValue) Type() Type
      func (vValue) Uint() uint64
      func (vValue) UnsafeAddr() uintptr
type ValueError
func (e *ValueError) Error() string
 
以下是学习Golang reflect的过程中参考到的一些比较有价值的相关资源连接
[1] GoLang反射的规则
http://www.tuicool.com/articles/7NjaQn
[2] Go 数据结构:接口
http://my.oschina.net/Obahua/blog/160458
[3] Reflect OfGolang
http://wendal.net/2012/1130.html
[4] golang的反射-Value
http://www.cnblogs.com/zhepama/archive/2013/04/12/3017204.html
[5] 无闻:【Go编程基础】13反射reflection|Go视频教程|Go语言基础教程
http://www.56.com/w41/play_album-aid-11263603_vid-OTMxNzUyOTc.html

本博客原创博文版权所有 @[email protected]
仅供交流学习使用用于商业用途请联系原作者 
转载请注明出处:http://blog.sina.com.cn/ally2014

你可能感兴趣的:(golang)