From 94192fbceb6eb17c7f4be5c9ed7609c480bc18ec Mon Sep 17 00:00:00 2001 From: John Date: Sat, 11 Aug 2018 22:31:28 +0800 Subject: [PATCH] =?UTF-8?q?gconv.MapToStruct=E6=96=B9=E6=B3=95=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E8=87=AA=E5=AE=9A=E4=B9=89=E5=8F=82=E6=95=B0=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E6=98=A0=E5=B0=84=E5=85=B3=E7=B3=BB=E5=8F=82=E6=95=B0?= =?UTF-8?q?=EF=BC=8C=E9=9D=9E=E5=BF=85=E9=9C=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/util/gconv/gconv.go | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/g/util/gconv/gconv.go b/g/util/gconv/gconv.go index 13892726b..45bb08b2a 100644 --- a/g/util/gconv/gconv.go +++ b/g/util/gconv/gconv.go @@ -299,11 +299,12 @@ func Float64 (i interface{}) float64 { return v } -// 将map键值对映射到对应的struct对象属性上,需要注意: +// 将params键值对参数映射到对应的struct对象属性上,第三个参数mapping为非必需,表示自定义名称与属性名称的映射关系。 +// 需要注意: // 1、第二个参数为struct对象指针; // 2、struct对象的**公开属性(首字母大写)**才能被映射赋值; // 3、map中的键名可以为小写,映射转换时会自动将键名首字母转为大写做匹配映射,如果无法匹配则忽略; -func MapToStruct(params map[string]interface{}, object interface{}) error { +func MapToStruct(params map[string]interface{}, object interface{}, mapping...map[string]string) error { tagmap := make(map[string]string) fields := structs.Fields(object) // 将struct中定义的属性转换名称构建称tagmap @@ -315,15 +316,36 @@ func MapToStruct(params map[string]interface{}, object interface{}) error { } } elem := reflect.ValueOf(object).Elem() - // 首先匹配对象定义时绑定的属性名称 + dmap := make(map[string]bool) + // 首先按照传递的映射关系进行匹配 + if len(mapping) > 0 { + for mappingk, mappingv := range mapping[0] { + if v, ok := params[mappingk]; ok { + dmap[mappingv] = true + bindVarToStruct(elem, mappingv, v) + } + } + } + // 其次匹配对象定义时绑定的属性名称 for tagk, tagv := range tagmap { + if _, ok := dmap[tagv]; ok { + continue + } if v, ok := params[tagk]; ok { + dmap[tagv] = true bindVarToStruct(elem, tagv, v) } } - // 其次按照默认规则进行匹配 + // 最后按照默认规则进行匹配 for mapk, mapv := range params { - bindVarToStruct(elem, gstr.UcFirst(mapk), mapv) + name := gstr.UcFirst(mapk) + if _, ok := dmap[name]; ok { + continue + } + // 后续tag逻辑中会处理的key(重复的键名)这里便不处理 + if _, ok := tagmap[mapk]; !ok { + bindVarToStruct(elem, name, mapv) + } } return nil }