反射包主要有一个接口:type,和一个结构value;
type接口
commonType类型实现了type接口,下面是type中的各类型关系
- commonType>unCommonType>method
- arrayType|chanType|funcType|interfaceType|mapType|ptrType|sliceType >commonType
- ptrMap>n*commonType
其他结构
Method结构
MethodByName()和Method()会返回这种类型
type Method struct { Name string PkgPath string Type Type // method type Func Value // func with receiver as first argument Index int // index for Type.Method }
structField结构
Field()和FieldByIndex(),以及FieldByName(),FieldByNameFunc会返回该类型
type structField struct { name *string // nil for embedded fields pkgPath *string // nil for exported Names; otherwise import path typ *runtimeType // type of field tag *string // nil if no tag offset uintptr // byte offset of field within struct }
反射一个变量的type,本质上是将这个变量的指针转换为commonType的指针
- 首先将变量的指针,通过unsafe包将类型转换为Pointer类型
- 然后将Pointer类型转换为*emptyInterface类型,并使用*表达式将其emptyInterface的值传给eface
- 断言eface.typ的值是否是commonType的指针类型,如果是则返回其值
func toType(p *runtimeType) Type { if p == nil { return nil } return (*p).(*commonType) } func TypeOf(i interface{}) Type { eface := *(*emptyInterface)(unsafe.Pointer(&i)) return toType(eface.typ) }
类型函数介绍
- func ChanOf(dir ChanDir, t Type) Type
- 返回channel type
- func MapOf(key, elem Type) Type
- 返回Map type
- func PtrTo(t Type) Type
- 返回指针类型
- func SliceOf(t Type) Type
- 返回slice类型
- func TypeOf(i interface{}) Type
- 反射变量类型,最好不要直接传指针进去.否则会有些东西发射不出.例如Name()
type类型方法介绍
- func (t *commonType) Align() int
- 类型在内容分配时,返回的字节的对齐方式
- func (t *commonType) FieldAlign() int
- 当类型作为一个结构的字段时,他的字节对齐方式
- func (t *commonType) Method(i int) (m Method)
- 通过整形索引,反射类型的方法,返回一个Method类型
type B struct { c string b byte a int } func (b B) test() { } func main() { b := B{} fmt.Println(reflect.TypeOf(b).Method(0).Name) //test }
- func (t *commonType) MethodByName(name string) (m Method, ok bool)
- 通过方法名,判断该类型是否有该方法,如果存在返回该方法,并且返回ok值为true
type B struct { c string b byte a int } func (b B) test() { } func main() { b := new(B) m, _ := reflect.TypeOf(b).MethodByName("test") fmt.Println(m.PkgPath) }
- func (t *commonType) NumMethod() int
- 返回该类型拥有的方法数量
- func (t *commonType) Name() string
- 返回类型的名称,如果是匿名类型将返回空字符窜,如果是指针,则什么都没有
- func (t *commonType) PkgPath() string
- 返回类型所在包的路径,如果是指针则什么都木有
- func (t *commonType) Size() uintptr
- 返回类型的大小
- func (t *commonType) String() string
- 返回类型的字符窜名称
- func (t *commonType) Kind() Kind
- 返回这个类型的特殊种类,(struct,ptr,func等)
- func (t *commonType) Implements(u Type) bool
- 判断类型是否实现u这个接口.注意u必须不能为nil,且是一个接口
- func (t *commonType) AssignableTo(u Type) bool
- 判断类型是否可分配到u类型
- func (t *commonType) Bits() int
- 反射类型的使用字节,如果不是Int,Uint,Float,complex种类则会产生恐慌
- func (t *commonType) ChanDir() ChanDir
- 反射channel 目录
- func (t *commonType) IsVariadic() bool
- 判断函数是否有可变参数(...)
type B struct { c string b byte a int } func (b B) test() { } func test(a ...int) { } func main() { fmt.Println(reflect.TypeOf(test).IsVariadic()) //true fmt.Println(reflect.TypeOf(B.test).IsVariadic()) //false }
- func (t *commonType) Elem() Type
- 返回一个类型的元素类型,种类非Array,chan,map,ptr,slice会产生恐慌
type B struct { c string b byte a int } func (b B) test() { } func main() { b := &B{} fmt.Println(reflect.TypeOf(b).Elem()) //main.B }
- func (t *commonType) Field(i int) StructField
- 根据索引返回一个结构的字段,值为StructField类型
- func (t *commonType) FieldByIndex(index []int) StructField
- 返回嵌套类型的字段结构.
type A struct { a int b byte c string } type B struct { A c string b byte a int } func (b B) test() { } func main() { b := B{} index := []int{0, 1} fmt.Println(reflect.TypeOf(b).FieldByIndex(index).Name) //b }
- func (t *commonType) FieldByName(name string) (StructField, bool)
- 根据字段名,反射该字段类型
- func (t *commonType) FieldByNameFunc(match func(string) bool) (StructField, bool)
- ....没明白
type B struct { c string b byte a int } func test(a string) bool { return true } func main() { b := B{} fmt.Println(reflect.TypeOf(b).FieldByNameFunc(test)) //{ 0 [] false} false }
- func (t *commonType) In(i int) Type
- 反射函数类型的第i个参数
func test(a string) bool { return true } func main() { fmt.Println(reflect.TypeOf(test).In(0)) }
- func (t *commonType) Key() Type
- 反射map类型的key的类型,如果不是map则会产生恐慌
- func (t *commonType) Len() int
- 反射array类型的长度,如果不是array,则会产生恐慌
- func (t *commonType) NumField() int
- 反射一个struct的字段数量,如果不是struct则会产生恐慌
- func (t *commonType) NumIn() int
- 反射一个func的输入参数的数量,如果不是函数则会产生恐慌
- func (t *commonType) NumOut() int
- 反射函数的返回结果的数量,入股不是函数则会产生恐慌
- func (t *commonType) Out(i int) Type
- 反射函数返回结果的i的类型,如果不是函数则产生恐慌,而且如果不在范围[0, NumOut()]则也会产生恐慌
题外话:声明变量其值为匿名结构
type T struct {} var t T var t struct {}