注意:反射获取字段给字段赋值时,该字段必须首字母大写,否则会引起恐慌报如下错误:
panic: reflect: reflect.flag.mustBeAssignable using value obtained using unexported field
1.变量结构
type,value(pair)
2.reflect包
1.reflect类型
const (Invalid Kind = iota //0~26BoolIntInt8Int16Int32Int64UintUint8Uint16Uint32Uint64UintptrFloat32Float64Complex64Complex128ArrayChanFuncInterfaceMapPtrSliceStringStructUnsafePointer //26)
2.获取kind
package mainimport "reflect"type User struct {Name stringAge int}func refTest(arg interface{}) {var argType reflect.Type = reflect.TypeOf(arg)var argValue reflect.Value = reflect.ValueOf(arg)print(argType.Kind())print(argValue.Kind())}func main() {refTest(User{"zhangsna", 11})//25 struct类型}
3.获取属性
package mainimport ("fmt""reflect")type User struct {//定义字段,并设置字段标签Name string `info:"名字" doc:"哈哈"`Age int `info:"年龄"`height float64 `info:"身高"`}func (user *User) GetName() string {return user.Name}//interface{}是万能数据类型func myFunc(arg interface{}) {//通过参数获取,参数的类型和值argType := reflect.TypeOf(arg)argValue := reflect.ValueOf(arg)//当arg是pir时,需要通过argType.Elem()获取属性,例如argType.Elem().NumField()for i := 0; i < argType.NumField(); i++ {//通过type获取内部字段类型和值field := argType.Field(i)value := argValue.Field(i)fmt.Println(field.Name, field.Type, value)//获取字段标签,Tag只存在类型里info := argType.Field(i).Tag.Get("info")doc := argType.Field(i).Tag.Get("doc")fmt.Println("标签info为:", info, "doc为", doc)}//通过type获取内部方法,只能获取非地址传值的方法for i := 0; i < argType.NumMethod(); i++ {method := argType.Method(i)fmt.Println(method.Name, method.Type)}}func main() {user := User{"张三", 24, 1.70}myFunc(user)}
4.反射修改值
package mainimport ("fmt""reflect")func refTest(arg interface{}) {argValue := reflect.ValueOf(arg)argValue.Elem().SetInt(10)}func main() {var a int = 11//必须传递指针refTest(&a)fmt.Println(a)}
5.反射调用方法
