mirror of
https://gitee.com/johng/gf
synced 2026-07-08 06:35:16 +08:00
改进gconv对象转换方法,名称修改gconv.MapToStruct -> gconv.Struct
This commit is contained in:
@ -10,41 +10,68 @@ package gvar
|
||||
import (
|
||||
"time"
|
||||
"gitee.com/johng/gf/g/util/gconv"
|
||||
"gitee.com/johng/gf/g/container/gtype"
|
||||
)
|
||||
|
||||
type Var struct {
|
||||
value interface{}
|
||||
value interface{} // 变量值
|
||||
safe bool // 当为true时,value为 *gtype.Interface 类型
|
||||
}
|
||||
|
||||
func New(value...interface{}) *Var {
|
||||
// 创建一个动态变量,value参数可以为nil
|
||||
func New(value interface{}, safe...bool) *Var {
|
||||
v := &Var{}
|
||||
if len(value) > 0 {
|
||||
v.value = value[0]
|
||||
if len(safe) > 0 && safe[0] {
|
||||
v.safe = safe[0]
|
||||
v.value = gtype.NewInterface(value)
|
||||
} else {
|
||||
v.value = value
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func (v *Var) IsNil() bool { return v.value == nil }
|
||||
func (v *Var) Bytes() []byte { return gconv.Bytes(v.value) }
|
||||
func (v *Var) String() string { return gconv.String(v.value) }
|
||||
func (v *Var) Bool() bool { return gconv.Bool(v.value) }
|
||||
func (v *Var) Set(value interface{}) {
|
||||
if v.safe {
|
||||
v.value.(*gtype.Interface).Set(value)
|
||||
} else {
|
||||
v.value = value
|
||||
}
|
||||
}
|
||||
|
||||
func (v *Var) Int() int { return gconv.Int(v.value) }
|
||||
func (v *Var) Int8() int8 { return gconv.Int8(v.value) }
|
||||
func (v *Var) Int16() int16 { return gconv.Int16(v.value) }
|
||||
func (v *Var) Int32() int32 { return gconv.Int32(v.value) }
|
||||
func (v *Var) Int64() int64 { return gconv.Int64(v.value) }
|
||||
func (v *Var) Val() interface{} {
|
||||
if v.safe {
|
||||
return v.value.(*gtype.Interface).Val()
|
||||
} else {
|
||||
return v.value
|
||||
}
|
||||
}
|
||||
|
||||
func (v *Var) Uint() uint { return gconv.Uint(v.value) }
|
||||
func (v *Var) Uint8() uint8 { return gconv.Uint8(v.value) }
|
||||
func (v *Var) Uint16() uint16 { return gconv.Uint16(v.value) }
|
||||
func (v *Var) Uint32() uint32 { return gconv.Uint32(v.value) }
|
||||
func (v *Var) Uint64() uint64 { return gconv.Uint64(v.value) }
|
||||
func (v *Var) IsNil() bool { return v.Val() == nil }
|
||||
func (v *Var) Bytes() []byte { return gconv.Bytes(v.Val()) }
|
||||
func (v *Var) String() string { return gconv.String(v.Val()) }
|
||||
func (v *Var) Bool() bool { return gconv.Bool(v.Val()) }
|
||||
|
||||
func (v *Var) Float32() float32 { return gconv.Float32(v.value) }
|
||||
func (v *Var) Float64() float64 { return gconv.Float64(v.value) }
|
||||
func (v *Var) Int() int { return gconv.Int(v.Val()) }
|
||||
func (v *Var) Int8() int8 { return gconv.Int8(v.Val()) }
|
||||
func (v *Var) Int16() int16 { return gconv.Int16(v.Val()) }
|
||||
func (v *Var) Int32() int32 { return gconv.Int32(v.Val()) }
|
||||
func (v *Var) Int64() int64 { return gconv.Int64(v.Val()) }
|
||||
|
||||
func (v *Var) Strings() []string { return gconv.Strings(v.value) }
|
||||
func (v *Var) Uint() uint { return gconv.Uint(v.Val()) }
|
||||
func (v *Var) Uint8() uint8 { return gconv.Uint8(v.Val()) }
|
||||
func (v *Var) Uint16() uint16 { return gconv.Uint16(v.Val()) }
|
||||
func (v *Var) Uint32() uint32 { return gconv.Uint32(v.Val()) }
|
||||
func (v *Var) Uint64() uint64 { return gconv.Uint64(v.Val()) }
|
||||
|
||||
func (v *Var) Time(format...string) time.Time { return gconv.Time(v.value, format...) }
|
||||
func (v *Var) TimeDuration() time.Duration { return gconv.TimeDuration(v.value) }
|
||||
func (v *Var) Float32() float32 { return gconv.Float32(v.Val()) }
|
||||
func (v *Var) Float64() float64 { return gconv.Float64(v.Val()) }
|
||||
|
||||
func (v *Var) Strings() []string { return gconv.Strings(v.Val()) }
|
||||
|
||||
func (v *Var) Time(format...string) time.Time { return gconv.Time(v.Val(), format...) }
|
||||
func (v *Var) TimeDuration() time.Duration { return gconv.TimeDuration(v.Val()) }
|
||||
|
||||
// 将变量转换为对象,注意 objPointer 参数必须为struct指针
|
||||
func (v *Var) Struct(objPointer interface{}, attrMapping...map[string]string) error {
|
||||
return gconv.Struct(v.Val(), objPointer, attrMapping...)
|
||||
}
|
||||
@ -38,5 +38,5 @@ func (r Record) ToStruct(obj interface{}) error {
|
||||
for k, v := range r {
|
||||
m[k] = v.String()
|
||||
}
|
||||
return gconv.MapToStruct(m, obj)
|
||||
return gconv.Struct(m, obj)
|
||||
}
|
||||
|
||||
@ -685,7 +685,7 @@ func (j *Json) ToToml() ([]byte, error) {
|
||||
func (j *Json) ToStruct(o interface{}) error {
|
||||
j.mu.RLock()
|
||||
defer j.mu.RUnlock()
|
||||
return gconv.MapToStruct(j.ToMap(), o)
|
||||
return gconv.Struct(j.ToMap(), o)
|
||||
}
|
||||
|
||||
// 打印Json对象
|
||||
|
||||
@ -146,5 +146,5 @@ func (r *Request) GetPostToStruct(object interface{}, mapping...map[string]strin
|
||||
for k, v := range r.GetPostMap() {
|
||||
params[k] = v
|
||||
}
|
||||
gconv.MapToStruct(params, object, tagmap)
|
||||
gconv.Struct(params, object, tagmap)
|
||||
}
|
||||
@ -145,5 +145,5 @@ func (r *Request) GetQueryToStruct(object interface{}, mapping...map[string]stri
|
||||
for k, v := range r.GetQueryMap() {
|
||||
params[k] = v
|
||||
}
|
||||
gconv.MapToStruct(params, object, tagmap)
|
||||
gconv.Struct(params, object, tagmap)
|
||||
}
|
||||
@ -130,6 +130,6 @@ func (r *Request) GetRequestToStruct(object interface{}, mapping...map[string]st
|
||||
for k, v := range r.GetRequestMap() {
|
||||
params[k] = v
|
||||
}
|
||||
gconv.MapToStruct(params, object, tagmap)
|
||||
gconv.Struct(params, object, tagmap)
|
||||
}
|
||||
|
||||
|
||||
@ -15,12 +15,37 @@ import (
|
||||
|
||||
// 将params键值对参数映射到对应的struct对象属性上,第三个参数mapping为非必需,表示自定义名称与属性名称的映射关系。
|
||||
// 需要注意:
|
||||
// 1、第二个参数为struct对象指针;
|
||||
// 1、第二个参数应当为struct对象指针;
|
||||
// 2、struct对象的**公开属性(首字母大写)**才能被映射赋值;
|
||||
// 3、map中的键名可以为小写,映射转换时会自动将键名首字母转为大写做匹配映射,如果无法匹配则忽略;
|
||||
func MapToStruct(params map[string]interface{}, object interface{}, mapping...map[string]string) error {
|
||||
func Struct(params interface{}, objPointer interface{}, attrMapping...map[string]string) error {
|
||||
isParamMap := true
|
||||
paramsMap := (map[string]interface{})(nil)
|
||||
// 先将参数转为 map[string]interface{} 类型
|
||||
if m, ok := params.(map[string]interface{}); ok {
|
||||
paramsMap = m
|
||||
} else {
|
||||
paramsMap = make(map[string]interface{})
|
||||
if reflect.ValueOf(params).Kind() == reflect.Map {
|
||||
ks := reflect.ValueOf(params).MapKeys()
|
||||
vs := reflect.ValueOf(params)
|
||||
for _, k := range ks {
|
||||
paramsMap[String(k.Interface())] = vs.MapIndex(k).Interface()
|
||||
}
|
||||
} else {
|
||||
isParamMap = false
|
||||
}
|
||||
}
|
||||
// struct的反射对象
|
||||
elem := reflect.ValueOf(objPointer).Elem()
|
||||
// 如果给定的参数不是map类型,那么直接将参数值映射到第一个属性上
|
||||
if !isParamMap {
|
||||
bindVarToStructByIndex(elem, 0, params)
|
||||
return nil
|
||||
}
|
||||
// 标签映射关系map,如果有的话
|
||||
tagmap := make(map[string]string)
|
||||
fields := structs.Fields(object)
|
||||
fields := structs.Fields(objPointer)
|
||||
// 将struct中定义的属性转换名称构建称tagmap
|
||||
for _, field := range fields {
|
||||
if tag := field.Tag("gconv"); tag != "" {
|
||||
@ -29,12 +54,11 @@ func MapToStruct(params map[string]interface{}, object interface{}, mapping...ma
|
||||
}
|
||||
}
|
||||
}
|
||||
elem := reflect.ValueOf(object).Elem()
|
||||
dmap := make(map[string]bool)
|
||||
// 首先按照传递的映射关系进行匹配
|
||||
if len(mapping) > 0 && len(mapping[0]) > 0 {
|
||||
for mappingk, mappingv := range mapping[0] {
|
||||
if v, ok := params[mappingk]; ok {
|
||||
if len(attrMapping) > 0 && len(attrMapping[0]) > 0 {
|
||||
for mappingk, mappingv := range attrMapping[0] {
|
||||
if v, ok := paramsMap[mappingk]; ok {
|
||||
dmap[mappingv] = true
|
||||
bindVarToStruct(elem, mappingv, v)
|
||||
}
|
||||
@ -45,13 +69,13 @@ func MapToStruct(params map[string]interface{}, object interface{}, mapping...ma
|
||||
if _, ok := dmap[tagv]; ok {
|
||||
continue
|
||||
}
|
||||
if v, ok := params[tagk]; ok {
|
||||
if v, ok := paramsMap[tagk]; ok {
|
||||
dmap[tagv] = true
|
||||
bindVarToStruct(elem, tagv, v)
|
||||
}
|
||||
}
|
||||
// 最后按照默认规则进行匹配
|
||||
for mapk, mapv := range params {
|
||||
for mapk, mapv := range paramsMap {
|
||||
name := gstr.UcFirst(mapk)
|
||||
if _, ok := dmap[name]; ok {
|
||||
continue
|
||||
@ -78,3 +102,19 @@ func bindVarToStruct(elem reflect.Value, name string, value interface{}) {
|
||||
// 必须将value转换为struct属性的数据类型,这里必须用到gconv包
|
||||
structFieldValue.Set(reflect.ValueOf(Convert(value, structFieldValue.Type().String())))
|
||||
}
|
||||
|
||||
// 将参数值绑定到对象指定索引位置的属性上
|
||||
func bindVarToStructByIndex(elem reflect.Value, index int, value interface{}) {
|
||||
structFieldValue := elem.FieldByIndex([]int{index})
|
||||
// 键名与对象属性匹配检测
|
||||
if !structFieldValue.IsValid() {
|
||||
return
|
||||
}
|
||||
// CanSet的属性必须为公开属性(首字母大写)
|
||||
if !structFieldValue.CanSet() {
|
||||
return
|
||||
}
|
||||
// 必须将value转换为struct属性的数据类型,这里必须用到gconv包
|
||||
structFieldValue.Set(reflect.ValueOf(Convert(value, structFieldValue.Type().String())))
|
||||
}
|
||||
|
||||
|
||||
4
geg/database/redis/config.tomll
Normal file
4
geg/database/redis/config.tomll
Normal file
@ -0,0 +1,4 @@
|
||||
# Redis数据库配置
|
||||
[redis]
|
||||
default = "127.0.0.1:6379,0"
|
||||
cache = "127.0.0.1:6379,1"
|
||||
@ -1,4 +0,0 @@
|
||||
# Redis数据库配置
|
||||
redis:
|
||||
default: 127.0.0.1:6379,0
|
||||
cache : 127.0.0.1:6379,1
|
||||
@ -24,7 +24,7 @@ func main() {
|
||||
"pass1" : "123",
|
||||
"pass2" : "123",
|
||||
}
|
||||
if err := gconv.MapToStruct(params1, user); err == nil {
|
||||
if err := gconv.Struct(params1, user); err == nil {
|
||||
fmt.Println(user)
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ func main() {
|
||||
"password1" : "456",
|
||||
"password2" : "456",
|
||||
}
|
||||
if err := gconv.MapToStruct(params2, user); err == nil {
|
||||
if err := gconv.Struct(params2, user); err == nil {
|
||||
fmt.Println(user)
|
||||
}
|
||||
}
|
||||
@ -15,10 +15,15 @@ func main() {
|
||||
user := new(User)
|
||||
scores := []int{99, 100, 60, 140}
|
||||
|
||||
err := gconv.MapToStruct(g.Map{
|
||||
"Scores" : scores,
|
||||
}, user)
|
||||
if err != nil {
|
||||
// 通过map映射转换
|
||||
if err := gconv.Struct(g.Map{"Scores" : scores}, user); err != nil {
|
||||
fmt.Println(err)
|
||||
} else {
|
||||
g.Dump(user)
|
||||
}
|
||||
|
||||
// 通过变量映射转换
|
||||
if err := gconv.Struct(scores, user); err != nil {
|
||||
fmt.Println(err)
|
||||
} else {
|
||||
g.Dump(user)
|
||||
|
||||
26
geg/util/gconv/gconv_struct3.go
Normal file
26
geg/util/gconv/gconv_struct3.go
Normal file
@ -0,0 +1,26 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"gitee.com/johng/gf/g/util/gconv"
|
||||
"gitee.com/johng/gf/g"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// 演示slice类型属性的赋值
|
||||
func main() {
|
||||
type User struct {
|
||||
Scores []int
|
||||
}
|
||||
|
||||
user := new(User)
|
||||
scores := []int{99, 100, 60, 140}
|
||||
|
||||
err := gconv.Struct(g.Map{
|
||||
"Scores" : scores,
|
||||
}, user)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
} else {
|
||||
g.Dump(user)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user