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) // Hello
fmt.Println(m.Type) // func(main.User)
}
}
func main() { u := User{1, “zs”, 20} Poni(u) }
<a name="pTbgQ"></a>
# 3 DeepEqual
```go
package main
import (
"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 main
import (
"errors"
"fmt"
"reflect"
)
type Employee struct {
Name string
Age int
}
type Customer struct {
Name string
Age 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.StructField
ok 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
}