1 简介
反射是指在程序运行期对程序本身进行访问和修改的能力
变量包含类型信息和值信息
- 类型信息:是静态的元信息,是预先定义好的
- 值信息:是程序运行过程中动态改变的
reflect包封装了反射相关的方法
import ( “fmt” “reflect” )
// 定义结构体 type User struct { Id int Name string Age int }
// 绑方法 func (u User) Hello() { fmt.Println(“Hello”) }
// 传入interface{} func Poni(o interface{}) { // 获取类型 t := reflect.TypeOf(o) fmt.Println(“类型:”, t) // main.User fmt.Println(“字符串类型:”, t.Name()) // User // 获取种类 k := t.Kind() fmt.Println(“种类:”, k) // struct // 获取值 v := reflect.ValueOf(o) fmt.Println(v) // {1 zs 20}
// 获取结构体字段个数:t.NumField()for i := 0; i < t.NumField(); i++ {// 取每个字段f := t.Field(i)fmt.Printf("%s : %v", f.Name, f.Type) // Id : int// 获取字段的值信息// Interface():获取字段对应的值val := v.Field(i).Interface()fmt.Println("val :", val) // val : 1}// 获取结构体方法个数:t.NumMethod()for i := 0; i < t.NumMethod(); i++ {m := t.Method(i)fmt.Println(m.Name) // Hellofmt.Println(m.Type) // func(main.User)}
}
func main() { u := User{1, “zs”, 20} Poni(u) }
<a name="pTbgQ"></a># 3 DeepEqual```gopackage mainimport ("fmt""reflect")func main() {s1 := []int{1, 2, 3}s2 := []int{1, 2, 3}s3 := []int{2, 3, 1}fmt.Println(reflect.DeepEqual(s1, s2), reflect.DeepEqual(s1, s3)) // true false}
package mainimport ("errors""fmt""reflect")type Employee struct {Name stringAge int}type Customer struct {Name stringAge int}func fillBySettings(st interface{}, settings map[string]interface{}) error {if settings == nil {return errors.New("settings is nil")}if reflect.TypeOf(st).Kind() != reflect.Ptr {return errors.New("第一参数应是 指针")}if reflect.TypeOf(st).Elem().Kind() != reflect.Struct { // Elem()获取指针 指向的值return errors.New("第一参数应是 结构体指针")}var (field reflect.StructFieldok bool)for k, v := range settings {if field, ok = (reflect.ValueOf(st)).Elem().Type().FieldByName(k); !ok {continue}if field.Type == reflect.TypeOf(v) {vstr := reflect.ValueOf(st)vstr = vstr.Elem()vstr.FieldByName(k).Set(reflect.ValueOf(v))}}return nil}func main() {settings := map[string]interface{}{"Name": "Mike", "Age": 40}e := &Employee{}_ = fillBySettings(e, settings)fmt.Println(e)c := new(Customer)_ = fillBySettings(c, settings)fmt.Println(c)fmt.Println(reflect.DeepEqual(e, c)) // false}
