反射 #
反射包名为reflect
func TypeOf(i interface{}) Type
reflect.TypeOf(任意类型变量) 返回反射的reflect.Type接口类型
var x float64 = 3.4
reflect.TypeOf(x).String() 等价 reflect.TypeOf(x).Name()
fmt.Println("type:", reflect.TypeOf(x).String()) //type: float64
func ValueOf(i interface{}) Value
reflect.ValueOf(变量名) 返回反射的reflect.Value结构体类型,用途:获取和设置变量的值
var x float64 = 3.4
fmt.Println("type:", reflect.ValueOf(x).Float()) //type: 3.4
v := reflect.ValueOf(x)
fmt.Println("type:", v.Type()) //type: float64
fmt.Println("kind is float64:", v.Kind() == reflect.Float64) //kind is float64: true
fmt.Println("value:", v.Float()) //value: 3.4
reflect.Type接口方法 #
type Type interface {
//
Align() int
//
FieldAlign() int
//获取第i个方法并返回reflect.Method结构体对象
Method(int) Method
//
MethodByName(string) (Method, bool)
//获取结构体中方法个数
NumMethod() int
//获取值类型名称,如int,string,bool,[]int等,等价 String()
Name() string
//
PkgPath() string
//
Size() uintptr
//获取值类型名称,如int,string,bool,[]int等,等价 Name()
String() string
//返回反射出来的值类型名,种类, Kind类型是unit类型:type Kind uint
Kind() Kind
//
Implements(u Type) bool
//
AssignableTo(u Type) bool
//
ConvertibleTo(u Type) bool
//
Comparable() bool
//
Bits() int
//
ChanDir() ChanDir
//
IsVariadic() bool
//取指针类型的元素类型,返回Type接口类型 It panics if the type's Kind is not Array, Chan, Map, Ptr, or Slice.
Elem() Type
//i表示获取第i个成员,从0开始,返回StructField结构体对象
Field(i int) StructField
//通过索引获取成员的StructField结构体对象
FieldByIndex(index []int) StructField
//通过结构体的字段名(即成员名)获取返回StructField结构体对象,第2个返回参数表示是否存在该字段名
FieldByName(name string) (StructField, bool)
//
FieldByNameFunc(match func(string) bool) (StructField, bool)
//
In(i int) Type
//
Key() Type
//
Len() int
//结构体中的字段个数(即成员个数)
NumField() int
//
NumIn() int
//
NumOut() int
//
Out(i int) Type
common() *rtype
uncommon() *uncommonType
}
reflect.Method内置结构体对象如下:
type Method struct {
Name string //方法名
PkgPath string
Type Type //方法类型,返回reflect.Type接口对象
Func Value //
Index int //在Type.Method结构体中的索引
}
更多文档: https://golang.google.cn/pkg/reflect/#Type
func New(typ Type) Value 把reflect.Type接口对象转reflect.Value结构体对象
示例:
var x float64 = 4.4
xType := reflect.TypeOf(x)
//输出:*float64 ptr
fmt.Println(reflect.New(xType).Type(), reflect.New(xType).Kind())
reflect.Value结构体支持的方法 #
返回reflect.Value结构体类型,用途:获取和设置变量的值
func ValueOf(i interface{}) Value
reflect.Value结构体支持的方法如下:
func (v Value) Type() Type 把reflect.Value对象转reflect.Type结构体对象
func (v Value) Interface() (i interface{}) 获取变量值
func (v Value) CanInterface() bool
func (v Value) Kind() Kind 返回种类,type Kind uint
func (v Value) Elem() Value 取值指向的元素值
func (v Value) Addr() Value 对可寻址的值返回其地址,类似于语言层& 操作。当值不可寻址时发生宕机
func (v Value) CanAddr() bool 表示值是否可寻址
func (v Value) UnsafeAddr() uintptr
func (v Value) String() string 将值以字符串类型返回,原变量值是字符串才可以
func (v Value) Bool() bool 将值以 bool 类型返回,原变量值是布尔型才可以
func (v Value) Int() int64 将值以 int64 类型返回,原变量值是int型才可以
func (v Value) Uint() uint64
func (v Value) Float() float64
func (v Value) IsNil() bool 判断值是否为nil
func (v Value) IsValid() bool 判断值是否有效
func (v Value) Index(i int) Value
func (v Value) Bytes() []byte 将值以字节数组 []bytes 类型返回
func (v Value) runes() []rune
func (v Value) Call(in []Value) []Value
func (v Value) CallSlice(in []Value) []Value
func (v Value) Cap() int
func (v Value) Close()
func (v Value) Complex() complex128
func (v Value) Convert(t Type) Value
func (v Value) NumField() int 结构体中的字段个数(即成员个数)
func (v Value) Field(i int) Value 根据索引获取字段对象并返回reflect.Value结构体对象
func (v Value) FieldByIndex(index []int) Value
func (v Value) FieldByName(name string) Value 通过结构体字段名获取字段对象并返回reflect.Value结构体对象
func (v Value) FieldByNameFunc(match func(string) bool) Value
func (v Value) Len() int
func (v Value) MapIndex(key Value) Value
func (v Value) MapKeys() []Value
func (v Value) NumMethod() int 返回方法个数
func (v Value) Method(i int) Value 获取第i个方法并返回reflect.Value结构体对象,下标从0开始算
func (v Value) MethodByName(name string) Value
func (v Value) OverflowComplex(x complex128) bool
func (v Value) OverflowFloat(x float64) bool
func (v Value) OverflowInt(x int64) bool
func (v Value) OverflowUint(x uint64) bool
func (v Value) Pointer() uintptr
func (v Value) Recv() (x Value, ok bool)
func (v Value) TryRecv() (x Value, ok bool)
func (v Value) Send(x Value)
func (v Value) TrySend(x Value) bool
func (v Value) CanSet() bool 判断值是否能被修改
func (v Value) Set(x Value)
func (v Value) SetBool(x bool)
func (v Value) SetBytes(x []byte)
func (v Value) SetCap(n int)
func (v Value) SetComplex(x complex128)
func (v Value) SetFloat(x float64)
func (v Value) SetInt(x int64)
func (v Value) SetUint(x uint64)
func (v Value) SetString(x string)
func (v Value) SetLen(n int)
func (v Value) SetMapIndex(key, val Value)
func (v Value) SetPointer(x unsafe.Pointer)
func (v Value) Slice(i, j int) Value
func (v Value) Slice3(i, j, k int) Value
更多文档:https://golang.google.cn/pkg/reflect/#Value
示例1:
Abc := 97
refVal := reflect.ValueOf(Abc)
fmt.Println(refVal.Type().Name(), refVal.Kind()) //int int
示例2:
abc := "hello"
refVal := reflect.ValueOf(abc)
fmt.Println(refVal.Interface()) //hello
reflect包内置类型常量 #
类型归属的种类(Kind)使用的是 reflect.Type接口中的 Kind() 方法获取
type Kind uint
const (
Invalid Kind = iota //非法类型
Bool //布尔类型
Int //有符号整型
Int8 //有符号8位整型
Int16 //有符号16位整型
Int32
Int64
Uint //无符号整型
Uint8 //无符号8位整型
Uint16
Uint32
Uint64
Uintptr //指针
Float32
Float64
Complex64
Complex128
Array //数组
Chan //通道、信道
Func //函数
Interface //接口
Map //映射,map类型
Ptr //指针
Slice //切片
String
Struct //结构体
UnsafePointer //底层指针
)
更多文档:https://golang.google.cn/pkg/reflect/#Kind
示例:
fmt.Println(reflect.TypeOf([]int{1,2}).Kind()) //slice
if reflect.TypeOf([]int{1,2}).Kind()==reflect.Slice {
fmt.Println("是切片类型")
}
反射包内置结构体:reflect.StructField结构体 #
type StructField struct {
//结构体的字段名
Name string
//字段路径
PkgPath string
Type Type //字段反射类型对象,即reflect.Type接口对象
Tag StructTag //字段的结构体标签,为结构体字段标签的额外信息,字符串类型值,type StructTag string
Offset uintptr //字段在结构体中的相对偏移
Index []int //Type.FieldByIndex返回的索引值
Anonymous bool //是否为匿名字段
}
备注:
结构体的标签格式写法:`key1:"value1" key2:"value2"`
示例:type cat struct {
Name string
Age int `json:"age" id:"100"`
}
StructTag结构体支持的方法如下:
func (tag StructTag) Get(key string) string 入参为tag名(如key1)返回值为key1对应的值如value1,key1不存在返回空
func (tag StructTag) Lookup(key string) (value string, ok bool) 入参为tag名(如key1)返回值为key1对应的值如value1,第2个返回值判断是否存在key1
反射示例1 #
package main
import (
"fmt"
"reflect"
)
func main() {
// 声明一个猫结构体
type cat struct {
//名称
Name string
// 带有结构体tag的字段
Age int `json:"age" id:"100"`
}
// 创建cat的实例
ins := cat{Name: "mimi", Age: 18}
//反射结构体实例返回reflect.Type接口对象
typeOfCat := reflect.TypeOf(ins)
//遍历结构体所有成员
for i := 0; i < typeOfCat.NumField(); i++ {
//获取第i个成员的结构体字段类型(即reflect.StructField结构体对象)
fieldType := typeOfCat.Field(i)
tmpKind := fieldType.Type.Kind() //值类型
//打印成员信息:名称和tag
fmt.Printf("成员名: %v tag: '%v' 索引:%#v 类型:%v json_tag:%v\n",
fieldType.Name, fieldType.Tag, fieldType.Index,tmpKind,fieldType.Tag.Get("json"))
}
}
输出结果如下:
成员名: Name tag: '' 索引:[]int{0} 类型:string json_tag:
成员名: Age tag: 'json:"age" id:"100"' 索引:[]int{1} 类型:int json_tag:age
反射示例2 #
package main
import (
"fmt"
"reflect"
"strings"
"time"
)
type xyz struct {
Age string
}
func (x *xyz) Hi() {
}
func main() {
abc := "hi"
DebugPrintReflect(abc)
DebugPrintReflect(time.Hour)
DebugPrintReflect(&xyz{})
}
func DebugPrintReflect(x interface{}) {
v := reflect.ValueOf(x) //反射,返回reflect.Value结构体对象
t := v.Type() //返回reflect.Type接口对象
fmt.Printf("类型为 %s,类型支持的方法如下:\n", t)
for i := 0; i < v.NumMethod(); i++ {
methType := v.Method(i).Type() //具体某个方法转成reflect.Type接口对象
fmt.Printf("func (%s) %s%s\n", t, t.Method(i).Name,
strings.TrimPrefix(methType.String(), "func"))
}
}