go 速学 - 14 - 反射
目录
摘要
使用反射,匿名字段,动态修改属性,动态调用方法
反射 reflection
使用反射
前提
使用反射之前必须引用包 reflect
定义一个结构及方法
import "reflect"
type User struct {
Id int
Name string
Age int
}
func (u User) say() {
fmt.Println("hello")
}
u := User{Id: 1, Name: "Peter", Age: 20}
反射所有字段及方法
reflect.TypeOf(o)
用于获得类型原型reflect.ValueOf(o)
用于获得值
注意要想访问字段的值则字段应为 public
,要想调用方法则方法应为 public
func info(o interface{}) {
//获得参数类型的原型
t := reflect.TypeOf(o)
fmt.Println("t", t) //t main.User
fmt.Println("t.Name()", t.Name()) //t.Name() User
fmt.Println("t.NumField()", t.NumField()) //t.NumField() 3
v := reflect.ValueOf(o)
fmt.Println("v", v) //v <main.User Value>
//检测类型
if k := t.Kind(); k != reflect.Struct {
return
}
//输出属性
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
//此时的 Field 必须为public
val := v.Field(i).Interface()
fmt.Println(f.Name, f.Type, val)
//--> outputs
//Id int 1
//Name string Peter
//Age int 20
}
fmt.Println()
//输出方法
for i := 0; i < t.NumMethod(); i++ {
m := t.Method(i)
fmt.Println(m.Name, m.Type)
//-->outputs
//say func(main.User)
}
}
info(u)
访问结构中的匿名字段
type Manager struct {
User
title string
}
//type
m := Manager{title: "Manager", User: User{Id: 2, Name: "Jane", Age: 22}}
t := reflect.TypeOf(m)
f := t.FieldByIndex([]int{0, 1})
fmt.Println("f", f.Name, f.Type) //f Name string
//value
v := reflect.ValueOf(m)
val := v.FieldByIndex([]int{0, 1}).Interface()
fmt.Println("val", val) //val Jane
使用 reflect.FieldByIndex()
方法,该方法的参数为 slice
,以上第一个位置的 “0” 表示 Manager 的0号属性(User),1表示 User 的1号属性(Name)
动态修改属性的值
func set(o interface{}) {
v := reflect.ValueOf(o)
////判断是否为指针类型且可写
if k := v.Kind(); k != reflect.Ptr || !v.Elem().CanSet() {
fmt.Println("invalid type")
return
}
v = v.Elem()
f := v.FieldByName("Name")
//判断指定属性是否存在
if !f.IsValid() {
fmt.Println("invalid name")
return
}
if f.Kind() == reflect.String {
f.SetString("a")
}
}
u := User{Id: 1, Name: "Peter", Age: 20}
fmt.Println("u.Name", u.Name) //u.Name Peter
set(&u)
fmt.Println("u.Name", u.Name) //u.Name a
set(u)
注意以上是通过传入指针来实现动态修改的
动态调用方法
注意调用方法时该方法应为 public
func (u User) Hello(name string) {
fmt.Println("hello ", name, " my name is ", u.Name)
}
u := User{Id: 1, Name: "Peter", Age: 20}
v = reflect.ValueOf(u)
mn := v.MethodByName("Hello")
args := []reflect.Value{reflect.ValueOf("Andy")}
mn.Call(args)
fmt.Println("u.Name", u.Name) //hello Andy my name is a
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。