您的位置:首页 > 编程语言 > Go语言

[golang]golang reflect详细用法整理

2014-11-09 19:55 253 查看
本博客原创博文版权所有 @Allyvipally@gmail.com
仅供交流学习使用用于商业用途请联系原作者
转载请注明出处: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 数据结构:接口
/article/3468278.html
[3]Reflect OfGolang http://wendal.net/2012/1130.html [4]golang的反射-Value
/article/5181891.html
[5]无闻:【Go编程基础】13反射reflection|Go视频教程|Go语言基础教程 http://www.56.com/w41/play_album-aid-11263603_vid-OTMxNzUyOTc.html
本博客原创博文版权所有 @Allyvipally@gmail.com
仅供交流学习使用用于商业用途请联系原作者
转载请注明出处:http://blog.sina.com.cn/ally2014
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: