示例代码请访问:github.com/wenjianzhan…
关于“反射”你应该知道的
- 提高了程序的灵活性
- 降低了程序的可读性
- 降低了程序的性能
示例代码
package ch36
import (
"errors"
"fmt"
"reflect"
"testing"
)
type Employee struct {
EmployeeID string
Name string `format:"normal"`
Age int
}
type Customer struct {
CookieID string
Name string
Age int
}
func TestDeepEqual(t *testing.T) {
a := map[int]string{1: "one", 2: "two", 3: "three"}
b := map[int]string{1: "one", 2: "two", 4: "three"}
//t.Log(a == b)
fmt.Println(reflect.DeepEqual(a, b))
s1 := []int{1, 2, 3}
s2 := []int{1, 2, 3}
s3 := []int{2, 3, 1}
t.Log("s1==s2?", reflect.DeepEqual(s1, s2))
t.Log("s1==s2?", reflect.DeepEqual(s1, s3))
}
func TestFillNameAnfAge(t *testing.T) {
settings := map[string]interface{}{"Name": "Mike", "Age": 40}
e := Employee{}
if err := fillBySettings(&e, settings); err != nil {
t.Fatal(err)
}
t.Log(e)
c := new(Customer)
if err := fillBySettings(c, settings); err != nil {
t.Fatal(err)
}
t.Log(*c)
}
func fillBySettings(st interface{}, settings map[string]interface{}) error {
if reflect.TypeOf(st).Kind() != reflect.Ptr {
if reflect.TypeOf(st).Elem().Kind() != reflect.Struct {
return errors.New("the first param should be a pointer to the struct type")
}
}
if settings == nil {
return errors.New("settings is nil.")
}
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
}
输出
=== RUN TestFillNameAnfAge
--- PASS: TestFillNameAnfAge (0.00s)
flexible_reflect_test.go:42: { Mike 40}
flexible_reflect_test.go:47: { Mike 40}
PASS
Process finished with exit code 0
示例代码请访问:github.com/wenjianzhan…