From 7357b79bd4bd383cfa439098ef7098f3f84235cf Mon Sep 17 00:00:00 2001 From: john Date: Sat, 29 Sep 2018 18:06:04 +0800 Subject: [PATCH] =?UTF-8?q?gconv.Struct=E6=94=B9=E8=BF=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/util/gconv/gconv_struct.go | 33 ++++++++++++++++++++++++++++++++- geg/other/test.go | 31 ++++++++++++------------------- geg/util/gconv/gconv_struct3.go | 20 +++++++++++++------- 3 files changed, 57 insertions(+), 27 deletions(-) diff --git a/g/util/gconv/gconv_struct.go b/g/util/gconv/gconv_struct.go index 858d752cd..137836b4b 100644 --- a/g/util/gconv/gconv_struct.go +++ b/g/util/gconv/gconv_struct.go @@ -13,6 +13,7 @@ import ( "strings" "errors" "fmt" + "os" ) // 将params键值对参数映射到对应的struct对象属性上,第三个参数mapping为非必需,表示自定义名称与属性名称的映射关系。 @@ -50,7 +51,7 @@ func Struct(params interface{}, objPointer interface{}, attrMapping...map[string // 标签映射关系map,如果有的话 tagmap := make(map[string]string) fields := structs.Fields(objPointer) - // 将struct中定义的属性转换名称构建称tagmap + // 将struct中定义的属性转换名称构建成tagmap for _, field := range fields { if tag := field.Tag("gconv"); tag != "" { for _, v := range strings.Split(tag, ",") { @@ -110,6 +111,36 @@ func bindVarToStruct(elem reflect.Value, name string, value interface{}) error { return errors.New(fmt.Sprintf(`struct attribute of name "%s" cannot be set`, name)) } // 必须将value转换为struct属性的数据类型,这里必须用到gconv包 + defer func() { + // 如果转换失败,那么可能是类型不匹配造成(例如属性包含自定义类型),那么执行递归转换 + if recover() != nil { + v := structFieldValue.Interface() + //Struct(value, &v) + //fmt.Println(structs.Fields(v)) + for _, field := range structs.Fields(v) { + fmt.Println(field.Name()) + } + fmt.Println(reflect.ValueOf(v).Kind()) + fmt.Println(reflect.ValueOf(&v).Elem().Kind()) + fmt.Println(v) + fmt.Println(reflect.TypeOf(v)) + os.Exit(1) + //v := reflect.New(structFieldValue.Type()).Interface() + //if b, err := json.Marshal(value); err == nil { + // if err := json.Unmarshal(b, &v); err == nil { + // + // } else { + // fmt.Println(err) + // } + //} else { + // fmt.Println(err) + //} + //fmt.Println(v) + //fmt.Println(reflect.TypeOf(v)) + //structFieldValue.Set(reflect.ValueOf(v).Elem()) + //os.Exit(1) + } + }() structFieldValue.Set(reflect.ValueOf(Convert(value, structFieldValue.Type().String()))) return nil } diff --git a/geg/other/test.go b/geg/other/test.go index 588aca492..62b8975be 100644 --- a/geg/other/test.go +++ b/geg/other/test.go @@ -1,28 +1,21 @@ package main import ( - "encoding/json" "fmt" + "reflect" ) -func main() { - type B struct { - Name string - } - type A struct { - Name string - Child B - } +type S struct { - a := A { - Name : "A", - Child : B { - Name : "B", - }, - } - b, _ := json.Marshal(a) - a2 := new(A) - json.Unmarshal(b, a2) - fmt.Println(*a2) +} + +func main() { + s := S{} + fmt.Println(reflect.ValueOf(s).Kind()) + fmt.Println(reflect.ValueOf(&s).Elem().Kind()) + + v := reflect.ValueOf(s).Interface() + fmt.Println(reflect.ValueOf(v).Kind()) + fmt.Println(reflect.ValueOf(&v).Elem().Type().PkgPath()) } diff --git a/geg/util/gconv/gconv_struct3.go b/geg/util/gconv/gconv_struct3.go index cf2e5f6e7..0240a2300 100644 --- a/geg/util/gconv/gconv_struct3.go +++ b/geg/util/gconv/gconv_struct3.go @@ -6,19 +6,25 @@ import ( "fmt" ) -// 演示slice类型属性的赋值 func main() { + type Score struct { + Name string + Result int + } type User struct { - Scores []int + Scores Score } user := new(User) - scores := []int{99, 100, 60, 140} + scores := map[string]interface{}{ + "Scores" : + map[string]interface{}{ + "Name" : "john", + "Result" : 100, + }, + } - err := gconv.Struct(g.Map{ - "Scores" : scores, - }, user) - if err != nil { + if err := gconv.Struct(scores, user); err != nil { fmt.Println(err) } else { g.Dump(user)