From d09978c87d9f1fda26fe97155b27569e146d4527 Mon Sep 17 00:00:00 2001 From: john Date: Tue, 9 Oct 2018 10:05:55 +0800 Subject: [PATCH] =?UTF-8?q?gconv=E5=A2=9E=E5=8A=A0Ints/Floats/Interfaces?= =?UTF-8?q?=E8=BD=AC=E6=8D=A2=E6=96=B9=E6=B3=95=EF=BC=8C=E5=AE=8C=E5=96=84?= =?UTF-8?q?gconv.Struct=E6=96=B9=E6=B3=95=E5=B0=81=E8=A3=85=EF=BC=8C?= =?UTF-8?q?=E6=94=B9=E8=BF=9B=E7=9B=B8=E5=85=B3=E4=BE=9D=E8=B5=96=E5=8C=85?= =?UTF-8?q?=E5=AF=B9gconv=E7=9A=84=E5=BC=95=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/container/gvar/gvar.go | 9 +++- g/encoding/gjson/gjson.go | 12 +++++ g/encoding/gparser/gparser.go | 12 +++++ g/net/ghttp/ghttp_request.go | 16 ++++++ g/net/ghttp/ghttp_request_post.go | 37 ++++++++++++++ g/net/ghttp/ghttp_request_query.go | 37 ++++++++++++++ g/net/ghttp/ghttp_request_request.go | 37 ++++++++++++++ g/os/gcfg/gcfg.go | 21 ++++++++ g/util/gconv/gconv_slice.go | 74 ++++++++++++++++++++++++++++ g/util/gconv/gconv_struct.go | 55 +++++++++++---------- 10 files changed, 283 insertions(+), 27 deletions(-) diff --git a/g/container/gvar/gvar.go b/g/container/gvar/gvar.go index c90879840..238119d3a 100644 --- a/g/container/gvar/gvar.go +++ b/g/container/gvar/gvar.go @@ -4,7 +4,7 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://gitee.com/johng/gf. -// 动态变量. +// 通用动态变量(支持并发安全). package gvar import ( @@ -46,6 +46,10 @@ func (v *Var) Val() interface{} { } } +func (v *Var) Interface() interface{} { + return v.Val() +} + 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()) } @@ -66,7 +70,10 @@ func (v *Var) Uint64() uint64 { return gconv.Uint64(v.Val()) } func (v *Var) Float32() float32 { return gconv.Float32(v.Val()) } func (v *Var) Float64() float64 { return gconv.Float64(v.Val()) } +func (v *Var) Ints() []int { return gconv.Ints(v.Val()) } +func (v *Var) Floats() []float64 { return gconv.Floats(v.Val()) } func (v *Var) Strings() []string { return gconv.Strings(v.Val()) } +func (v *Var) Interfaces() []interface{} { return gconv.Interfaces(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()) } diff --git a/g/encoding/gjson/gjson.go b/g/encoding/gjson/gjson.go index 48e380f10..ebf771fd2 100644 --- a/g/encoding/gjson/gjson.go +++ b/g/encoding/gjson/gjson.go @@ -218,6 +218,10 @@ func (j *Json) GetStrings(pattern string) []string { return gconv.Strings(j.Get(pattern)) } +func (j *Json) GetInterfaces(pattern string) []interface{} { + return gconv.Interfaces(j.Get(pattern)) +} + func (j *Json) GetTime(pattern string, format ... string) time.Time { return gconv.Time(j.Get(pattern), format...) } @@ -251,6 +255,10 @@ func (j *Json) GetInt64(pattern string) int64 { return gconv.Int64(j.Get(pattern)) } +func (j *Json) GetInts(pattern string) []int { + return gconv.Ints(j.Get(pattern)) +} + func (j *Json) GetUint(pattern string) uint { return gconv.Uint(j.Get(pattern)) } @@ -279,6 +287,10 @@ func (j *Json) GetFloat64(pattern string) float64 { return gconv.Float64(j.Get(pattern)) } +func (j *Json) GetFloats(pattern string) []float64 { + return gconv.Floats(j.Get(pattern)) +} + // 将指定变量转换为struct对象(对象属性赋值) func (j *Json) GetToStruct(pattern string, objPointer interface{}) error { return gconv.Struct(j.Get(pattern), objPointer) diff --git a/g/encoding/gparser/gparser.go b/g/encoding/gparser/gparser.go index e2122e258..317e5cc31 100644 --- a/g/encoding/gparser/gparser.go +++ b/g/encoding/gparser/gparser.go @@ -85,6 +85,10 @@ func (p *Parser) GetStrings(pattern string) []string { return p.json.GetStrings(pattern) } +func (p *Parser) GetInterfaces(pattern string) []interface{} { + return p.json.GetInterfaces(pattern) +} + func (p *Parser) GetTime(pattern string, format ... string) time.Time { return p.json.GetTime(pattern, format...) } @@ -118,6 +122,10 @@ func (p *Parser) GetInt64(pattern string) int64 { return p.json.GetInt64(pattern) } +func (p *Parser) GetInts(pattern string) []int { + return p.json.GetInts(pattern) +} + func (p *Parser) GetUint(pattern string) uint { return p.json.GetUint(pattern) } @@ -146,6 +154,10 @@ func (p *Parser) GetFloat64(pattern string) float64 { return p.json.GetFloat64(pattern) } +func (p *Parser) GetFloats(pattern string) []float64 { + return p.json.GetFloats(pattern) +} + // 将指定变量转换为struct对象(对象属性赋值) func (p *Parser) GetToStruct(pattern string, objPointer interface{}) error { return p.json.GetToStruct(pattern, objPointer) diff --git a/g/net/ghttp/ghttp_request.go b/g/net/ghttp/ghttp_request.go index a7ea33af5..220fc0e64 100644 --- a/g/net/ghttp/ghttp_request.go +++ b/g/net/ghttp/ghttp_request.go @@ -104,6 +104,10 @@ func (r *Request) GetInt(key string, def ... int) int { return r.GetRequestInt(key, def...) } +func (r *Request) GetInts(key string, def ... []int) []int { + return r.GetRequestInts(key, def...) +} + func (r *Request) GetUint(key string, def ... uint) uint { return r.GetRequestUint(key, def...) } @@ -116,10 +120,22 @@ func (r *Request) GetFloat64(key string, def ... float64) float64 { return r.GetRequestFloat64(key, def...) } +func (r *Request) GetFloats(key string, def ... []float64) []float64 { + return r.GetRequestFloats(key, def...) +} + func (r *Request) GetArray(key string, def ... []string) []string { return r.GetRequestArray(key, def...) } +func (r *Request) GetStrings(key string, def ... []string) []string { + return r.GetRequestStrings(key, def...) +} + +func (r *Request) GetInterfaces(key string, def ... []interface{}) []interface{} { + return r.GetRequestInterfaces(key, def...) +} + func (r *Request) GetMap(def...map[string]string) map[string]string { return r.GetRequestMap(def...) } diff --git a/g/net/ghttp/ghttp_request_post.go b/g/net/ghttp/ghttp_request_post.go index f5186112c..4956f17d6 100644 --- a/g/net/ghttp/ghttp_request_post.go +++ b/g/net/ghttp/ghttp_request_post.go @@ -76,6 +76,17 @@ func (r *Request) GetPostInt(key string, def ... int) int { return 0 } +func (r *Request) GetPostInts(key string, def ... []int) []int { + value := r.GetPost(key) + if value != nil { + return gconv.Ints(value) + } + if len(def) > 0 { + return def[0] + } + return nil +} + func (r *Request) GetPostUint(key string, def ... uint) uint { value := r.GetPostString(key) if value != "" { @@ -109,10 +120,36 @@ func (r *Request) GetPostFloat64(key string, def ... float64) float64 { return 0 } +func (r *Request) GetPostFloats(key string, def ... []float64) []float64 { + value := r.GetPost(key) + if value != nil { + return gconv.Floats(value) + } + if len(def) > 0 { + return def[0] + } + return nil +} + func (r *Request) GetPostArray(key string, def ... []string) []string { return r.GetPost(key, def...) } +func (r *Request) GetPostStrings(key string, def ... []string) []string { + return r.GetPost(key, def...) +} + +func (r *Request) GetPostInterfaces(key string, def ... []interface{}) []interface{} { + value := r.GetPost(key) + if value != nil { + return gconv.Interfaces(value) + } + if len(def) > 0 { + return def[0] + } + return nil +} + // 获取指定键名的关联数组,并且给定当指定键名不存在时的默认值 // 需要注意的是,如果其中一个字段为数组形式,那么只会返回第一个元素,如果需要获取全部的元素,请使用GetPostArray获取特定字段内容 func (r *Request) GetPostMap(def...map[string]string) map[string]string { diff --git a/g/net/ghttp/ghttp_request_query.go b/g/net/ghttp/ghttp_request_query.go index 3d04ecbfe..51f233ee8 100644 --- a/g/net/ghttp/ghttp_request_query.go +++ b/g/net/ghttp/ghttp_request_query.go @@ -75,6 +75,17 @@ func (r *Request) GetQueryInt(key string, def ... int) int { return 0 } +func (r *Request) GetQueryInts(key string, def ... []int) []int { + value := r.GetQuery(key) + if value != nil { + return gconv.Ints(value) + } + if len(def) > 0 { + return def[0] + } + return nil +} + func (r *Request) GetQueryUint(key string, def ... uint) uint { value := r.GetQueryString(key) if value != "" { @@ -108,10 +119,36 @@ func (r *Request) GetQueryFloat64(key string, def ... float64) float64 { return 0 } +func (r *Request) GetQueryFloats(key string, def ... []float64) []float64 { + value := r.GetQuery(key) + if value != nil { + return gconv.Floats(value) + } + if len(def) > 0 { + return def[0] + } + return nil +} + func (r *Request) GetQueryArray(key string, def ... []string) []string { return r.GetQuery(key, def...) } +func (r *Request) GetQueryStrings(key string, def ... []string) []string { + return r.GetQuery(key, def...) +} + +func (r *Request) GetQueryInterfaces(key string, def ... []interface{}) []interface{} { + value := r.GetQuery(key) + if value != nil { + return gconv.Interfaces(value) + } + if len(def) > 0 { + return def[0] + } + return nil +} + // 获取指定键名的关联数组,并且给定当指定键名不存在时的默认值 func (r *Request) GetQueryMap(def ... map[string]string) map[string]string { r.initGet() diff --git a/g/net/ghttp/ghttp_request_request.go b/g/net/ghttp/ghttp_request_request.go index 45a0184ab..35c53d856 100644 --- a/g/net/ghttp/ghttp_request_request.go +++ b/g/net/ghttp/ghttp_request_request.go @@ -58,6 +58,17 @@ func (r *Request) GetRequestInt(key string, def ... int) int { return 0 } +func (r *Request) GetRequestInts(key string, def ... []int) []int { + value := r.GetRequest(key) + if value != nil { + return gconv.Ints(value) + } + if len(def) > 0 { + return def[0] + } + return nil +} + func (r *Request) GetRequestUint(key string, def ... uint) uint { value := r.GetRequestString(key) if value != "" { @@ -91,10 +102,36 @@ func (r *Request) GetRequestFloat64(key string, def ... float64) float64 { return 0 } +func (r *Request) GetRequestFloats(key string, def ... []float64) []float64 { + value := r.GetRequest(key) + if value != nil { + return gconv.Floats(value) + } + if len(def) > 0 { + return def[0] + } + return nil +} + func (r *Request) GetRequestArray(key string, def ... []string) []string { return r.GetRequest(key, def...) } +func (r *Request) GetRequestStrings(key string, def ... []string) []string { + return r.GetRequest(key, def...) +} + +func (r *Request) GetRequestInterfaces(key string, def ... []interface{}) []interface{} { + value := r.GetRequest(key) + if value != nil { + return gconv.Interfaces(value) + } + if len(def) > 0 { + return def[0] + } + return nil +} + // 获取指定键名的关联数组,并且给定当指定键名不存在时的默认值 // 需要注意的是,如果其中一个字段为数组形式,那么只会返回第一个元素,如果需要获取全部的元素,请使用GetRequestArray获取特定字段内容 func (r *Request) GetRequestMap(def...map[string]string) map[string]string { diff --git a/g/os/gcfg/gcfg.go b/g/os/gcfg/gcfg.go index ee474af7e..c13b34f44 100644 --- a/g/os/gcfg/gcfg.go +++ b/g/os/gcfg/gcfg.go @@ -153,6 +153,13 @@ func (c *Config) GetStrings(pattern string, file...string) []string { return nil } +func (c *Config) GetInterfaces(pattern string, file...string) []interface{} { + if j := c.getJson(file...); j != nil { + return j.GetInterfaces(pattern) + } + return nil +} + // 返回指定json中的bool func (c *Config) GetBool(pattern string, file...string) bool { if j := c.getJson(file...); j != nil { @@ -177,6 +184,13 @@ func (c *Config) GetFloat64(pattern string, file...string) float64 { return 0 } +func (c *Config) GetFloats(pattern string, file...string) []float64 { + if j := c.getJson(file...); j != nil { + return j.GetFloats(pattern) + } + return nil +} + // 返回指定json中的float64->int func (c *Config) GetInt(pattern string, file...string) int { if j := c.getJson(file...); j != nil { @@ -214,6 +228,13 @@ func (c *Config) GetInt64(pattern string, file...string) int64 { return 0 } +func (c *Config) GetInts(pattern string, file...string) []int { + if j := c.getJson(file...); j != nil { + return j.GetInts(pattern) + } + return nil +} + // 返回指定json中的float64->uint func (c *Config) GetUint(pattern string, file...string) uint { if j := c.getJson(file...); j != nil { diff --git a/g/util/gconv/gconv_slice.go b/g/util/gconv/gconv_slice.go index 8d2eaf3dd..8f8a35782 100644 --- a/g/util/gconv/gconv_slice.go +++ b/g/util/gconv/gconv_slice.go @@ -228,4 +228,78 @@ func Floats(i interface{}) []float64 { } } return []float64{Float64(i)} +} + +// 任意类型转换为[]interface{}类型 +func Interfaces(i interface{}) []interface{} { + if i == nil { + return nil + } + if r, ok := i.([]interface{}); ok { + return r + } else { + array := make([]interface{}, 0) + switch i.(type) { + case []string: + for _, v := range i.([]string) { + array = append(array, v) + } + case []int: + for _, v := range i.([]int) { + array = append(array, v) + } + case []int8: + for _, v := range i.([]int8) { + array = append(array, v) + } + case []int16: + for _, v := range i.([]int16) { + array = append(array, v) + } + case []int32: + for _, v := range i.([]int32) { + array = append(array, v) + } + case []int64: + for _, v := range i.([]int64) { + array = append(array, v) + } + case []uint: + for _, v := range i.([]uint) { + array = append(array, v) + } + case []uint8: + for _, v := range i.([]uint8) { + array = append(array, v) + } + case []uint16: + for _, v := range i.([]uint16) { + array = append(array, v) + } + case []uint32: + for _, v := range i.([]uint32) { + array = append(array, v) + } + case []uint64: + for _, v := range i.([]uint64) { + array = append(array, v) + } + case []bool: + for _, v := range i.([]bool) { + array = append(array, v) + } + case []float32: + for _, v := range i.([]float32) { + array = append(array, v) + } + case []float64: + for _, v := range i.([]float64) { + array = append(array, v) + } + } + if len(array) > 0 { + return array + } + } + return []interface{}{i} } \ No newline at end of file diff --git a/g/util/gconv/gconv_struct.go b/g/util/gconv/gconv_struct.go index 88416ad79..245ab9f52 100644 --- a/g/util/gconv/gconv_struct.go +++ b/g/util/gconv/gconv_struct.go @@ -134,29 +134,7 @@ func bindVarToStruct(elem reflect.Value, name string, value interface{}) error { defer func() { // 如果转换失败,那么可能是类型不匹配造成(例如属性包含自定义类型),那么执行递归转换 if recover() != nil { - switch structFieldValue.Kind() { - case reflect.Struct: - Struct(value, structFieldValue) - case reflect.Slice: - a := reflect.Value{} - v := reflect.ValueOf(value) - if v.Kind() == reflect.Slice { - a = reflect.MakeSlice(structFieldValue.Type(), v.Len(), v.Len()) - for i := 0; i < v.Len(); i++ { - n := reflect.New(structFieldValue.Type().Elem()).Elem() - Struct(v.Index(i).Interface(), n) - a.Index(i).Set(n) - } - } else { - a = reflect.MakeSlice(structFieldValue.Type(), 1, 1) - n := reflect.New(structFieldValue.Type().Elem()).Elem() - Struct(value, n) - a.Index(0).Set(n) - } - structFieldValue.Set(a) - default: - panic(errors.New(fmt.Sprintf(`cannot convert to type "%s"`, structFieldValue.Type().String()))) - } + bindVarToStructIfDefaultConvertionFailed(structFieldValue, value) } }() structFieldValue.Set(reflect.ValueOf(Convert(value, structFieldValue.Type().String()))) @@ -178,12 +156,37 @@ func bindVarToStructByIndex(elem reflect.Value, index int, value interface{}) er defer func() { // 如果转换失败,那么可能是类型不匹配造成(例如属性包含自定义类型),那么执行递归转换 if recover() != nil { - if structFieldValue.Kind() == reflect.Struct { - Struct(value, structFieldValue) - } + bindVarToStructIfDefaultConvertionFailed(structFieldValue, value) } }() structFieldValue.Set(reflect.ValueOf(Convert(value, structFieldValue.Type().String()))) return nil } +// 当默认的基本类型转换失败时,通过recover判断后执行反射类型转换 +func bindVarToStructIfDefaultConvertionFailed(structFieldValue reflect.Value, value interface{}) { + switch structFieldValue.Kind() { + case reflect.Struct: + Struct(value, structFieldValue) + case reflect.Slice: + a := reflect.Value{} + v := reflect.ValueOf(value) + if v.Kind() == reflect.Slice { + a = reflect.MakeSlice(structFieldValue.Type(), v.Len(), v.Len()) + for i := 0; i < v.Len(); i++ { + n := reflect.New(structFieldValue.Type().Elem()).Elem() + Struct(v.Index(i).Interface(), n) + a.Index(i).Set(n) + } + } else { + a = reflect.MakeSlice(structFieldValue.Type(), 1, 1) + n := reflect.New(structFieldValue.Type().Elem()).Elem() + Struct(value, n) + a.Index(0).Set(n) + } + structFieldValue.Set(a) + default: + panic(errors.New(fmt.Sprintf(`cannot convert to type "%s"`, structFieldValue.Type().String()))) + } +} +