From 72251b880a4984c94ae641aa94fa25f5b02f851c Mon Sep 17 00:00:00 2001 From: jianchenma Date: Fri, 5 Feb 2021 14:44:20 +0800 Subject: [PATCH] improve package gconv for slice converting --- database/gdb/gdb_core_tracing.go | 5 +- util/gconv/gconv.go | 310 +++++++++++++------------- util/gconv/gconv_slice.go | 8 +- util/gconv/gconv_slice_any.go | 18 +- util/gconv/gconv_slice_float.go | 96 +++++--- util/gconv/gconv_slice_int.go | 126 ++++++++--- util/gconv/gconv_slice_str.go | 44 ++-- util/gconv/gconv_slice_uint.go | 132 +++++++---- util/gconv/gconv_time.go | 22 +- util/gconv/gconv_z_unit_all_test.go | 60 ++--- util/gconv/gconv_z_unit_bool_test.go | 4 +- util/gconv/gconv_z_unit_slice_test.go | 8 + 12 files changed, 496 insertions(+), 337 deletions(-) diff --git a/database/gdb/gdb_core_tracing.go b/database/gdb/gdb_core_tracing.go index 4ad920f1d..1ccfae3c7 100644 --- a/database/gdb/gdb_core_tracing.go +++ b/database/gdb/gdb_core_tracing.go @@ -38,7 +38,10 @@ func (c *Core) addSqlToTracing(ctx context.Context, sql *Sql) { if !gtrace.IsActivated(ctx) { return } - tr := otel.GetTracerProvider().Tracer(tracingInstrumentName, trace.WithInstrumentationVersion(gf.VERSION)) + tr := otel.GetTracerProvider().Tracer( + tracingInstrumentName, + trace.WithInstrumentationVersion(gf.VERSION), + ) ctx, span := tr.Start(ctx, sql.Type, trace.WithSpanKind(trace.SpanKindInternal)) defer span.End() diff --git a/util/gconv/gconv.go b/util/gconv/gconv.go index 0814e254c..75a16afc9 100644 --- a/util/gconv/gconv.go +++ b/util/gconv/gconv.go @@ -48,281 +48,281 @@ var ( // Convert converts the variable to the type , the type is specified by string. // The optional parameter is used for additional necessary parameter for this conversion. // It supports common types conversion as its conversion based on type name string. -func Convert(i interface{}, t string, params ...interface{}) interface{} { +func Convert(any interface{}, t string, params ...interface{}) interface{} { switch t { case "int": - return Int(i) + return Int(any) case "*int": - if _, ok := i.(*int); ok { - return i + if _, ok := any.(*int); ok { + return any } - v := Int(i) + v := Int(any) return &v case "int8": - return Int8(i) + return Int8(any) case "*int8": - if _, ok := i.(*int8); ok { - return i + if _, ok := any.(*int8); ok { + return any } - v := Int8(i) + v := Int8(any) return &v case "int16": - return Int16(i) + return Int16(any) case "*int16": - if _, ok := i.(*int16); ok { - return i + if _, ok := any.(*int16); ok { + return any } - v := Int16(i) + v := Int16(any) return &v case "int32": - return Int32(i) + return Int32(any) case "*int32": - if _, ok := i.(*int32); ok { - return i + if _, ok := any.(*int32); ok { + return any } - v := Int32(i) + v := Int32(any) return &v case "int64": - return Int64(i) + return Int64(any) case "*int64": - if _, ok := i.(*int64); ok { - return i + if _, ok := any.(*int64); ok { + return any } - v := Int64(i) + v := Int64(any) return &v case "uint": - return Uint(i) + return Uint(any) case "*uint": - if _, ok := i.(*uint); ok { - return i + if _, ok := any.(*uint); ok { + return any } - v := Uint(i) + v := Uint(any) return &v case "uint8": - return Uint8(i) + return Uint8(any) case "*uint8": - if _, ok := i.(*uint8); ok { - return i + if _, ok := any.(*uint8); ok { + return any } - v := Uint8(i) + v := Uint8(any) return &v case "uint16": - return Uint16(i) + return Uint16(any) case "*uint16": - if _, ok := i.(*uint16); ok { - return i + if _, ok := any.(*uint16); ok { + return any } - v := Uint16(i) + v := Uint16(any) return &v case "uint32": - return Uint32(i) + return Uint32(any) case "*uint32": - if _, ok := i.(*uint32); ok { - return i + if _, ok := any.(*uint32); ok { + return any } - v := Uint32(i) + v := Uint32(any) return &v case "uint64": - return Uint64(i) + return Uint64(any) case "*uint64": - if _, ok := i.(*uint64); ok { - return i + if _, ok := any.(*uint64); ok { + return any } - v := Uint64(i) + v := Uint64(any) return &v case "float32": - return Float32(i) + return Float32(any) case "*float32": - if _, ok := i.(*float32); ok { - return i + if _, ok := any.(*float32); ok { + return any } - v := Float32(i) + v := Float32(any) return &v case "float64": - return Float64(i) + return Float64(any) case "*float64": - if _, ok := i.(*float64); ok { - return i + if _, ok := any.(*float64); ok { + return any } - v := Float64(i) + v := Float64(any) return &v case "bool": - return Bool(i) + return Bool(any) case "*bool": - if _, ok := i.(*bool); ok { - return i + if _, ok := any.(*bool); ok { + return any } - v := Bool(i) + v := Bool(any) return &v case "string": - return String(i) + return String(any) case "*string": - if _, ok := i.(*string); ok { - return i + if _, ok := any.(*string); ok { + return any } - v := String(i) + v := String(any) return &v case "[]byte": - return Bytes(i) + return Bytes(any) case "[]int": - return Ints(i) + return Ints(any) case "[]int32": - return Int32s(i) + return Int32s(any) case "[]int64": - return Int64s(i) + return Int64s(any) case "[]uint": - return Uints(i) + return Uints(any) case "[]uint32": - return Uint32s(i) + return Uint32s(any) case "[]uint64": - return Uint64s(i) + return Uint64s(any) case "[]float32": - return Float32s(i) + return Float32s(any) case "[]float64": - return Float64s(i) + return Float64s(any) case "[]string": - return Strings(i) + return Strings(any) case "Time", "time.Time": if len(params) > 0 { - return Time(i, String(params[0])) + return Time(any, String(params[0])) } - return Time(i) + return Time(any) case "*time.Time": var v interface{} if len(params) > 0 { - v = Time(i, String(params[0])) + v = Time(any, String(params[0])) } else { - if _, ok := i.(*time.Time); ok { - return i + if _, ok := any.(*time.Time); ok { + return any } - v = Time(i) + v = Time(any) } return &v case "GTime", "gtime.Time": if len(params) > 0 { - if v := GTime(i, String(params[0])); v != nil { + if v := GTime(any, String(params[0])); v != nil { return *v } else { return *gtime.New() } } - if v := GTime(i); v != nil { + if v := GTime(any); v != nil { return *v } else { return *gtime.New() } case "*gtime.Time": if len(params) > 0 { - if v := GTime(i, String(params[0])); v != nil { + if v := GTime(any, String(params[0])); v != nil { return v } else { return gtime.New() } } - if v := GTime(i); v != nil { + if v := GTime(any); v != nil { return v } else { return gtime.New() } case "Duration", "time.Duration": - return Duration(i) + return Duration(any) case "*time.Duration": - if _, ok := i.(*time.Duration); ok { - return i + if _, ok := any.(*time.Duration); ok { + return any } - v := Duration(i) + v := Duration(any) return &v case "map[string]string": - return MapStrStr(i) + return MapStrStr(any) case "map[string]interface{}": - return Map(i) + return Map(any) case "[]map[string]interface{}": - return Maps(i) + return Maps(any) //case "gvar.Var": // // TODO remove reflect usage to create gvar.Var, considering using unsafe pointer // rv := reflect.New(intstore.ReflectTypeVarImp) // ri := rv.Interface() // if v, ok := ri.(apiSet); ok { - // v.Set(i) + // v.Set(any) // } else if v, ok := ri.(apiUnmarshalValue); ok { - // v.UnmarshalValue(i) + // v.UnmarshalValue(any) // } else { - // rv.Set(reflect.ValueOf(i)) + // rv.Set(reflect.ValueOf(any)) // } // return ri default: - return i + return any } } // Byte converts to byte. -func Byte(i interface{}) byte { - if v, ok := i.(byte); ok { +func Byte(any interface{}) byte { + if v, ok := any.(byte); ok { return v } - return Uint8(i) + return Uint8(any) } // Bytes converts to []byte. -func Bytes(i interface{}) []byte { - if i == nil { +func Bytes(any interface{}) []byte { + if any == nil { return nil } - switch value := i.(type) { + switch value := any.(type) { case string: return []byte(value) case []byte: return value default: - return gbinary.Encode(i) + return gbinary.Encode(any) } } // Rune converts to rune. -func Rune(i interface{}) rune { - if v, ok := i.(rune); ok { +func Rune(any interface{}) rune { + if v, ok := any.(rune); ok { return v } - return rune(Int32(i)) + return rune(Int32(any)) } // Runes converts to []rune. -func Runes(i interface{}) []rune { - if v, ok := i.([]rune); ok { +func Runes(any interface{}) []rune { + if v, ok := any.([]rune); ok { return v } - return []rune(String(i)) + return []rune(String(any)) } // String converts to string. // It's most common used converting function. -func String(i interface{}) string { - if i == nil { +func String(any interface{}) string { + if any == nil { return "" } - switch value := i.(type) { + switch value := any.(type) { case int: return strconv.Itoa(value) case int8: @@ -421,11 +421,11 @@ func String(i interface{}) string { // Bool converts to bool. // It returns false if is: false, "", 0, "false", "off", "no", empty slice/map. -func Bool(i interface{}) bool { - if i == nil { +func Bool(any interface{}) bool { + if any == nil { return false } - switch value := i.(type) { + switch value := any.(type) { case bool: return value case []byte: @@ -439,7 +439,7 @@ func Bool(i interface{}) bool { } return true default: - rv := reflect.ValueOf(i) + rv := reflect.ValueOf(any) switch rv.Kind() { case reflect.Ptr: return !rv.IsNil() @@ -452,7 +452,7 @@ func Bool(i interface{}) bool { case reflect.Struct: return true default: - s := strings.ToLower(String(i)) + s := strings.ToLower(String(any)) if _, ok := emptyStringMap[s]; ok { return false } @@ -462,55 +462,55 @@ func Bool(i interface{}) bool { } // Int converts to int. -func Int(i interface{}) int { - if i == nil { +func Int(any interface{}) int { + if any == nil { return 0 } - if v, ok := i.(int); ok { + if v, ok := any.(int); ok { return v } - return int(Int64(i)) + return int(Int64(any)) } // Int8 converts to int8. -func Int8(i interface{}) int8 { - if i == nil { +func Int8(any interface{}) int8 { + if any == nil { return 0 } - if v, ok := i.(int8); ok { + if v, ok := any.(int8); ok { return v } - return int8(Int64(i)) + return int8(Int64(any)) } // Int16 converts to int16. -func Int16(i interface{}) int16 { - if i == nil { +func Int16(any interface{}) int16 { + if any == nil { return 0 } - if v, ok := i.(int16); ok { + if v, ok := any.(int16); ok { return v } - return int16(Int64(i)) + return int16(Int64(any)) } // Int32 converts to int32. -func Int32(i interface{}) int32 { - if i == nil { +func Int32(any interface{}) int32 { + if any == nil { return 0 } - if v, ok := i.(int32); ok { + if v, ok := any.(int32); ok { return v } - return int32(Int64(i)) + return int32(Int64(any)) } // Int64 converts to int64. -func Int64(i interface{}) int64 { - if i == nil { +func Int64(any interface{}) int64 { + if any == nil { return 0 } - switch value := i.(type) { + switch value := any.(type) { case int: return int64(value) case int8: @@ -584,55 +584,55 @@ func Int64(i interface{}) int64 { } // Uint converts to uint. -func Uint(i interface{}) uint { - if i == nil { +func Uint(any interface{}) uint { + if any == nil { return 0 } - if v, ok := i.(uint); ok { + if v, ok := any.(uint); ok { return v } - return uint(Uint64(i)) + return uint(Uint64(any)) } // Uint8 converts to uint8. -func Uint8(i interface{}) uint8 { - if i == nil { +func Uint8(any interface{}) uint8 { + if any == nil { return 0 } - if v, ok := i.(uint8); ok { + if v, ok := any.(uint8); ok { return v } - return uint8(Uint64(i)) + return uint8(Uint64(any)) } // Uint16 converts to uint16. -func Uint16(i interface{}) uint16 { - if i == nil { +func Uint16(any interface{}) uint16 { + if any == nil { return 0 } - if v, ok := i.(uint16); ok { + if v, ok := any.(uint16); ok { return v } - return uint16(Uint64(i)) + return uint16(Uint64(any)) } // Uint32 converts to uint32. -func Uint32(i interface{}) uint32 { - if i == nil { +func Uint32(any interface{}) uint32 { + if any == nil { return 0 } - if v, ok := i.(uint32); ok { + if v, ok := any.(uint32); ok { return v } - return uint32(Uint64(i)) + return uint32(Uint64(any)) } // Uint64 converts to uint64. -func Uint64(i interface{}) uint64 { - if i == nil { +func Uint64(any interface{}) uint64 { + if any == nil { return 0 } - switch value := i.(type) { + switch value := any.(type) { case int: return uint64(value) case int8: @@ -688,11 +688,11 @@ func Uint64(i interface{}) uint64 { } // Float32 converts to float32. -func Float32(i interface{}) float32 { - if i == nil { +func Float32(any interface{}) float32 { + if any == nil { return 0 } - switch value := i.(type) { + switch value := any.(type) { case float32: return value case float64: @@ -700,17 +700,17 @@ func Float32(i interface{}) float32 { case []byte: return gbinary.DecodeToFloat32(value) default: - v, _ := strconv.ParseFloat(String(i), 64) + v, _ := strconv.ParseFloat(String(any), 64) return float32(v) } } // Float64 converts to float64. -func Float64(i interface{}) float64 { - if i == nil { +func Float64(any interface{}) float64 { + if any == nil { return 0 } - switch value := i.(type) { + switch value := any.(type) { case float32: return float64(value) case float64: @@ -718,7 +718,7 @@ func Float64(i interface{}) float64 { case []byte: return gbinary.DecodeToFloat64(value) default: - v, _ := strconv.ParseFloat(String(i), 64) + v, _ := strconv.ParseFloat(String(any), 64) return v } } diff --git a/util/gconv/gconv_slice.go b/util/gconv/gconv_slice.go index aa3878cda..265dd4d3a 100644 --- a/util/gconv/gconv_slice.go +++ b/util/gconv/gconv_slice.go @@ -11,13 +11,13 @@ import ( ) // SliceMap is alias of Maps. -func SliceMap(i interface{}) []map[string]interface{} { - return Maps(i) +func SliceMap(any interface{}) []map[string]interface{} { + return Maps(any) } // SliceMapDeep is alias of MapsDeep. -func SliceMapDeep(i interface{}) []map[string]interface{} { - return MapsDeep(i) +func SliceMapDeep(any interface{}) []map[string]interface{} { + return MapsDeep(any) } // SliceStruct is alias of Structs. diff --git a/util/gconv/gconv_slice_any.go b/util/gconv/gconv_slice_any.go index 6a6749a3a..865d21452 100644 --- a/util/gconv/gconv_slice_any.go +++ b/util/gconv/gconv_slice_any.go @@ -11,22 +11,22 @@ import ( ) // SliceAny is alias of Interfaces. -func SliceAny(i interface{}) []interface{} { - return Interfaces(i) +func SliceAny(any interface{}) []interface{} { + return Interfaces(any) } // Interfaces converts to []interface{}. -func Interfaces(i interface{}) []interface{} { - if i == nil { +func Interfaces(any interface{}) []interface{} { + if any == nil { return nil } - if r, ok := i.([]interface{}); ok { + if r, ok := any.([]interface{}); ok { return r - } else if r, ok := i.(apiInterfaces); ok { + } else if r, ok := any.(apiInterfaces); ok { return r.Interfaces() } else { var array []interface{} - switch value := i.(type) { + switch value := any.(type) { case []string: array = make([]interface{}, len(value)) for k, v := range value { @@ -99,7 +99,7 @@ func Interfaces(i interface{}) []interface{} { default: // Finally we use reflection. var ( - reflectValue = reflect.ValueOf(i) + reflectValue = reflect.ValueOf(any) reflectKind = reflectValue.Kind() ) for reflectKind == reflect.Ptr { @@ -130,7 +130,7 @@ func Interfaces(i interface{}) []interface{} { // array = append(array, v) // } default: - return []interface{}{i} + return []interface{}{any} } } return array diff --git a/util/gconv/gconv_slice_float.go b/util/gconv/gconv_slice_float.go index 465703fc2..56c1f7f4b 100644 --- a/util/gconv/gconv_slice_float.go +++ b/util/gconv/gconv_slice_float.go @@ -9,32 +9,32 @@ package gconv import "reflect" // SliceFloat is alias of Floats. -func SliceFloat(i interface{}) []float64 { - return Floats(i) +func SliceFloat(any interface{}) []float64 { + return Floats(any) } // SliceFloat32 is alias of Float32s. -func SliceFloat32(i interface{}) []float32 { - return Float32s(i) +func SliceFloat32(any interface{}) []float32 { + return Float32s(any) } // SliceFloat64 is alias of Float64s. -func SliceFloat64(i interface{}) []float64 { - return Floats(i) +func SliceFloat64(any interface{}) []float64 { + return Floats(any) } // Floats converts to []float64. -func Floats(i interface{}) []float64 { - return Float64s(i) +func Floats(any interface{}) []float64 { + return Float64s(any) } // Float32s converts to []float32. -func Float32s(i interface{}) []float32 { - if i == nil { +func Float32s(any interface{}) []float32 { + if any == nil { return nil } var array []float32 - switch value := i.(type) { + switch value := any.(type) { case string: if value == "" { return []float32{} @@ -112,35 +112,49 @@ func Float32s(i interface{}) []float32 { array[k] = Float32(v) } default: - if v, ok := i.(apiFloats); ok { + if v, ok := any.(apiFloats); ok { return Float32s(v.Floats()) } - if v, ok := i.(apiInterfaces); ok { + if v, ok := any.(apiInterfaces); ok { return Float32s(v.Interfaces()) } - // Use reflect feature at last. - rv := reflect.ValueOf(i) - switch rv.Kind() { + // Not a common type, it then uses reflection for conversion. + var reflectValue reflect.Value + if v, ok := value.(reflect.Value); ok { + reflectValue = v + } else { + reflectValue = reflect.ValueOf(value) + } + reflectKind := reflectValue.Kind() + for reflectKind == reflect.Ptr { + reflectValue = reflectValue.Elem() + reflectKind = reflectValue.Kind() + } + switch reflectKind { case reflect.Slice, reflect.Array: - length := rv.Len() - array = make([]float32, length) - for n := 0; n < length; n++ { - array[n] = Float32(rv.Index(n).Interface()) + var ( + length = reflectValue.Len() + slice = make([]float32, length) + ) + for i := 0; i < length; i++ { + slice[i] = Float32(reflectValue.Index(i).Interface()) } + return slice + default: - return []float32{Float32(i)} + return []float32{Float32(any)} } } return array } // Float64s converts to []float64. -func Float64s(i interface{}) []float64 { - if i == nil { +func Float64s(any interface{}) []float64 { + if any == nil { return nil } var array []float64 - switch value := i.(type) { + switch value := any.(type) { case string: if value == "" { return []float64{} @@ -218,23 +232,37 @@ func Float64s(i interface{}) []float64 { array[k] = Float64(v) } default: - if v, ok := i.(apiFloats); ok { + if v, ok := any.(apiFloats); ok { return v.Floats() } - if v, ok := i.(apiInterfaces); ok { + if v, ok := any.(apiInterfaces); ok { return Floats(v.Interfaces()) } - // Use reflect feature at last. - rv := reflect.ValueOf(i) - switch rv.Kind() { + // Not a common type, it then uses reflection for conversion. + var reflectValue reflect.Value + if v, ok := value.(reflect.Value); ok { + reflectValue = v + } else { + reflectValue = reflect.ValueOf(value) + } + reflectKind := reflectValue.Kind() + for reflectKind == reflect.Ptr { + reflectValue = reflectValue.Elem() + reflectKind = reflectValue.Kind() + } + switch reflectKind { case reflect.Slice, reflect.Array: - length := rv.Len() - array = make([]float64, length) - for n := 0; n < length; n++ { - array[n] = Float64(rv.Index(n).Interface()) + var ( + length = reflectValue.Len() + slice = make([]float64, length) + ) + for i := 0; i < length; i++ { + slice[i] = Float64(reflectValue.Index(i).Interface()) } + return slice + default: - return []float64{Float64(i)} + return []float64{Float64(any)} } } return array diff --git a/util/gconv/gconv_slice_int.go b/util/gconv/gconv_slice_int.go index 385cefcee..0fa2e680c 100644 --- a/util/gconv/gconv_slice_int.go +++ b/util/gconv/gconv_slice_int.go @@ -9,27 +9,27 @@ package gconv import "reflect" // SliceInt is alias of Ints. -func SliceInt(i interface{}) []int { - return Ints(i) +func SliceInt(any interface{}) []int { + return Ints(any) } // SliceInt32 is alias of Int32s. -func SliceInt32(i interface{}) []int32 { - return Int32s(i) +func SliceInt32(any interface{}) []int32 { + return Int32s(any) } // SliceInt is alias of Int64s. -func SliceInt64(i interface{}) []int64 { - return Int64s(i) +func SliceInt64(any interface{}) []int64 { + return Int64s(any) } // Ints converts to []int. -func Ints(i interface{}) []int { - if i == nil { +func Ints(any interface{}) []int { + if any == nil { return nil } var array []int - switch value := i.(type) { + switch value := any.(type) { case string: if value == "" { return []int{} @@ -117,35 +117,49 @@ func Ints(i interface{}) []int { array[k] = Int(v) } default: - if v, ok := i.(apiInts); ok { + if v, ok := any.(apiInts); ok { return v.Ints() } - if v, ok := i.(apiInterfaces); ok { + if v, ok := any.(apiInterfaces); ok { return Ints(v.Interfaces()) } - // Use reflect feature at last. - rv := reflect.ValueOf(i) - switch rv.Kind() { + // Not a common type, it then uses reflection for conversion. + var reflectValue reflect.Value + if v, ok := value.(reflect.Value); ok { + reflectValue = v + } else { + reflectValue = reflect.ValueOf(value) + } + reflectKind := reflectValue.Kind() + for reflectKind == reflect.Ptr { + reflectValue = reflectValue.Elem() + reflectKind = reflectValue.Kind() + } + switch reflectKind { case reflect.Slice, reflect.Array: - length := rv.Len() - array = make([]int, length) - for n := 0; n < length; n++ { - array[n] = Int(rv.Index(n).Interface()) + var ( + length = reflectValue.Len() + slice = make([]int, length) + ) + for i := 0; i < length; i++ { + slice[i] = Int(reflectValue.Index(i).Interface()) } + return slice + default: - return []int{Int(i)} + return []int{Int(any)} } } return array } // Int32s converts to []int32. -func Int32s(i interface{}) []int32 { - if i == nil { +func Int32s(any interface{}) []int32 { + if any == nil { return nil } var array []int32 - switch value := i.(type) { + switch value := any.(type) { case string: if value == "" { return []int32{} @@ -233,24 +247,49 @@ func Int32s(i interface{}) []int32 { array[k] = Int32(v) } default: - if v, ok := i.(apiInts); ok { + if v, ok := any.(apiInts); ok { return Int32s(v.Ints()) } - if v, ok := i.(apiInterfaces); ok { + if v, ok := any.(apiInterfaces); ok { return Int32s(v.Interfaces()) } - return []int32{Int32(i)} + // Not a common type, it then uses reflection for conversion. + var reflectValue reflect.Value + if v, ok := value.(reflect.Value); ok { + reflectValue = v + } else { + reflectValue = reflect.ValueOf(value) + } + reflectKind := reflectValue.Kind() + for reflectKind == reflect.Ptr { + reflectValue = reflectValue.Elem() + reflectKind = reflectValue.Kind() + } + switch reflectKind { + case reflect.Slice, reflect.Array: + var ( + length = reflectValue.Len() + slice = make([]int32, length) + ) + for i := 0; i < length; i++ { + slice[i] = Int32(reflectValue.Index(i).Interface()) + } + return slice + + default: + return []int32{Int32(any)} + } } return array } // Int64s converts to []int64. -func Int64s(i interface{}) []int64 { - if i == nil { +func Int64s(any interface{}) []int64 { + if any == nil { return nil } var array []int64 - switch value := i.(type) { + switch value := any.(type) { case string: if value == "" { return []int64{} @@ -338,13 +377,38 @@ func Int64s(i interface{}) []int64 { array[k] = Int64(v) } default: - if v, ok := i.(apiInts); ok { + if v, ok := any.(apiInts); ok { return Int64s(v.Ints()) } - if v, ok := i.(apiInterfaces); ok { + if v, ok := any.(apiInterfaces); ok { return Int64s(v.Interfaces()) } - return []int64{Int64(i)} + // Not a common type, it then uses reflection for conversion. + var reflectValue reflect.Value + if v, ok := value.(reflect.Value); ok { + reflectValue = v + } else { + reflectValue = reflect.ValueOf(value) + } + reflectKind := reflectValue.Kind() + for reflectKind == reflect.Ptr { + reflectValue = reflectValue.Elem() + reflectKind = reflectValue.Kind() + } + switch reflectKind { + case reflect.Slice, reflect.Array: + var ( + length = reflectValue.Len() + slice = make([]int64, length) + ) + for i := 0; i < length; i++ { + slice[i] = Int64(reflectValue.Index(i).Interface()) + } + return slice + + default: + return []int64{Int64(any)} + } } return array } diff --git a/util/gconv/gconv_slice_str.go b/util/gconv/gconv_slice_str.go index f4841ec82..02c24f288 100644 --- a/util/gconv/gconv_slice_str.go +++ b/util/gconv/gconv_slice_str.go @@ -9,17 +9,17 @@ package gconv import "reflect" // SliceStr is alias of Strings. -func SliceStr(i interface{}) []string { - return Strings(i) +func SliceStr(any interface{}) []string { + return Strings(any) } // Strings converts to []string. -func Strings(i interface{}) []string { - if i == nil { +func Strings(any interface{}) []string { + if any == nil { return nil } var array []string - switch value := i.(type) { + switch value := any.(type) { case []int: array = make([]string, len(value)) for k, v := range value { @@ -98,23 +98,37 @@ func Strings(i interface{}) []string { array[k] = String(v) } default: - if v, ok := i.(apiStrings); ok { + if v, ok := any.(apiStrings); ok { return v.Strings() } - if v, ok := i.(apiInterfaces); ok { + if v, ok := any.(apiInterfaces); ok { return Strings(v.Interfaces()) } - // Use reflect feature at last. - rv := reflect.ValueOf(i) - switch rv.Kind() { + // Not a common type, it then uses reflection for conversion. + var reflectValue reflect.Value + if v, ok := value.(reflect.Value); ok { + reflectValue = v + } else { + reflectValue = reflect.ValueOf(value) + } + reflectKind := reflectValue.Kind() + for reflectKind == reflect.Ptr { + reflectValue = reflectValue.Elem() + reflectKind = reflectValue.Kind() + } + switch reflectKind { case reflect.Slice, reflect.Array: - length := rv.Len() - array = make([]string, length) - for n := 0; n < length; n++ { - array[n] = String(rv.Index(n).Interface()) + var ( + length = reflectValue.Len() + slice = make([]string, length) + ) + for i := 0; i < length; i++ { + slice[i] = String(reflectValue.Index(i).Interface()) } + return slice + default: - return []string{String(i)} + return []string{String(any)} } } return array diff --git a/util/gconv/gconv_slice_uint.go b/util/gconv/gconv_slice_uint.go index 167812c97..8573ffd5b 100644 --- a/util/gconv/gconv_slice_uint.go +++ b/util/gconv/gconv_slice_uint.go @@ -9,28 +9,28 @@ package gconv import "reflect" // SliceUint is alias of Uints. -func SliceUint(i interface{}) []uint { - return Uints(i) +func SliceUint(any interface{}) []uint { + return Uints(any) } // SliceUint32 is alias of Uint32s. -func SliceUint32(i interface{}) []uint32 { - return Uint32s(i) +func SliceUint32(any interface{}) []uint32 { + return Uint32s(any) } // SliceUint64 is alias of Uint64s. -func SliceUint64(i interface{}) []uint64 { - return Uint64s(i) +func SliceUint64(any interface{}) []uint64 { + return Uint64s(any) } // Uints converts to []uint. -func Uints(i interface{}) []uint { - if i == nil { +func Uints(any interface{}) []uint { + if any == nil { return nil } var array []uint - switch value := i.(type) { + switch value := any.(type) { case string: if value == "" { return []uint{} @@ -113,35 +113,49 @@ func Uints(i interface{}) []uint { array[k] = Uint(v) } default: - if v, ok := i.(apiUints); ok { + if v, ok := any.(apiUints); ok { return v.Uints() } - if v, ok := i.(apiInterfaces); ok { + if v, ok := any.(apiInterfaces); ok { return Uints(v.Interfaces()) } - // Use reflect feature at last. - rv := reflect.ValueOf(i) - switch rv.Kind() { + // Not a common type, it then uses reflection for conversion. + var reflectValue reflect.Value + if v, ok := value.(reflect.Value); ok { + reflectValue = v + } else { + reflectValue = reflect.ValueOf(value) + } + reflectKind := reflectValue.Kind() + for reflectKind == reflect.Ptr { + reflectValue = reflectValue.Elem() + reflectKind = reflectValue.Kind() + } + switch reflectKind { case reflect.Slice, reflect.Array: - length := rv.Len() - array = make([]uint, length) - for n := 0; n < length; n++ { - array[n] = Uint(rv.Index(n).Interface()) + var ( + length = reflectValue.Len() + slice = make([]uint, length) + ) + for i := 0; i < length; i++ { + slice[i] = Uint(reflectValue.Index(i).Interface()) } + return slice + default: - return []uint{Uint(i)} + return []uint{Uint(any)} } } return array } // Uint32s converts to []uint32. -func Uint32s(i interface{}) []uint32 { - if i == nil { +func Uint32s(any interface{}) []uint32 { + if any == nil { return nil } var array []uint32 - switch value := i.(type) { + switch value := any.(type) { case string: if value == "" { return []uint32{} @@ -224,35 +238,49 @@ func Uint32s(i interface{}) []uint32 { array[k] = Uint32(v) } default: - if v, ok := i.(apiUints); ok { + if v, ok := any.(apiUints); ok { return Uint32s(v.Uints()) } - if v, ok := i.(apiInterfaces); ok { + if v, ok := any.(apiInterfaces); ok { return Uint32s(v.Interfaces()) } - // Use reflect feature at last. - rv := reflect.ValueOf(i) - switch rv.Kind() { + // Not a common type, it then uses reflection for conversion. + var reflectValue reflect.Value + if v, ok := value.(reflect.Value); ok { + reflectValue = v + } else { + reflectValue = reflect.ValueOf(value) + } + reflectKind := reflectValue.Kind() + for reflectKind == reflect.Ptr { + reflectValue = reflectValue.Elem() + reflectKind = reflectValue.Kind() + } + switch reflectKind { case reflect.Slice, reflect.Array: - length := rv.Len() - array = make([]uint32, length) - for n := 0; n < length; n++ { - array[n] = Uint32(rv.Index(n).Interface()) + var ( + length = reflectValue.Len() + slice = make([]uint32, length) + ) + for i := 0; i < length; i++ { + slice[i] = Uint32(reflectValue.Index(i).Interface()) } + return slice + default: - return []uint32{Uint32(i)} + return []uint32{Uint32(any)} } } return array } // Uint64s converts to []uint64. -func Uint64s(i interface{}) []uint64 { - if i == nil { +func Uint64s(any interface{}) []uint64 { + if any == nil { return nil } var array []uint64 - switch value := i.(type) { + switch value := any.(type) { case string: if value == "" { return []uint64{} @@ -335,23 +363,37 @@ func Uint64s(i interface{}) []uint64 { array[k] = Uint64(v) } default: - if v, ok := i.(apiUints); ok { + if v, ok := any.(apiUints); ok { return Uint64s(v.Uints()) } - if v, ok := i.(apiInterfaces); ok { + if v, ok := any.(apiInterfaces); ok { return Uint64s(v.Interfaces()) } - // Use reflect feature at last. - rv := reflect.ValueOf(i) - switch rv.Kind() { + // Not a common type, it then uses reflection for conversion. + var reflectValue reflect.Value + if v, ok := value.(reflect.Value); ok { + reflectValue = v + } else { + reflectValue = reflect.ValueOf(value) + } + reflectKind := reflectValue.Kind() + for reflectKind == reflect.Ptr { + reflectValue = reflectValue.Elem() + reflectKind = reflectValue.Kind() + } + switch reflectKind { case reflect.Slice, reflect.Array: - length := rv.Len() - array = make([]uint64, length) - for n := 0; n < length; n++ { - array[n] = Uint64(rv.Index(n).Interface()) + var ( + length = reflectValue.Len() + slice = make([]uint64, length) + ) + for i := 0; i < length; i++ { + slice[i] = Uint64(reflectValue.Index(i).Interface()) } + return slice + default: - return []uint64{Uint64(i)} + return []uint64{Uint64(any)} } } return array diff --git a/util/gconv/gconv_time.go b/util/gconv/gconv_time.go index c55daec06..866cd3513 100644 --- a/util/gconv/gconv_time.go +++ b/util/gconv/gconv_time.go @@ -14,14 +14,14 @@ import ( ) // Time converts to time.Time. -func Time(i interface{}, format ...string) time.Time { +func Time(any interface{}, format ...string) time.Time { // It's already this type. if len(format) == 0 { - if v, ok := i.(time.Time); ok { + if v, ok := any.(time.Time); ok { return v } } - if t := GTime(i, format...); t != nil { + if t := GTime(any, format...); t != nil { return t.Time } return time.Time{} @@ -30,34 +30,34 @@ func Time(i interface{}, format ...string) time.Time { // Duration converts to time.Duration. // If is string, then it uses time.ParseDuration to convert it. // If is numeric, then it converts as nanoseconds. -func Duration(i interface{}) time.Duration { +func Duration(any interface{}) time.Duration { // It's already this type. - if v, ok := i.(time.Duration); ok { + if v, ok := any.(time.Duration); ok { return v } - s := String(i) + s := String(any) if !utils.IsNumeric(s) { d, _ := gtime.ParseDuration(s) return d } - return time.Duration(Int64(i)) + return time.Duration(Int64(any)) } // GTime converts to *gtime.Time. // The parameter can be used to specify the format of . // If no given, it converts using gtime.NewFromTimeStamp if is numeric, // or using gtime.StrToTime if is string. -func GTime(i interface{}, format ...string) *gtime.Time { - if i == nil { +func GTime(any interface{}, format ...string) *gtime.Time { + if any == nil { return nil } // It's already this type. if len(format) == 0 { - if v, ok := i.(*gtime.Time); ok { + if v, ok := any.(*gtime.Time); ok { return v } } - s := String(i) + s := String(any) if len(s) == 0 { return gtime.New() } diff --git a/util/gconv/gconv_z_unit_all_test.go b/util/gconv/gconv_z_unit_all_test.go index c70ec6e3f..2441e8e6b 100644 --- a/util/gconv/gconv_z_unit_all_test.go +++ b/util/gconv/gconv_z_unit_all_test.go @@ -38,8 +38,8 @@ func (s1 S1) Error() string { func Test_Bool_All(t *testing.T) { gtest.C(t, func(t *gtest.T) { - var i interface{} = nil - t.AssertEQ(gconv.Bool(i), false) + var any interface{} = nil + t.AssertEQ(gconv.Bool(any), false) t.AssertEQ(gconv.Bool(false), false) t.AssertEQ(gconv.Bool(nil), false) t.AssertEQ(gconv.Bool(0), false) @@ -72,8 +72,8 @@ func Test_Bool_All(t *testing.T) { func Test_Int_All(t *testing.T) { gtest.C(t, func(t *gtest.T) { - var i interface{} = nil - t.AssertEQ(gconv.Int(i), 0) + var any interface{} = nil + t.AssertEQ(gconv.Int(any), 0) t.AssertEQ(gconv.Int(false), 0) t.AssertEQ(gconv.Int(nil), 0) t.Assert(gconv.Int(nil), 0) @@ -107,8 +107,8 @@ func Test_Int_All(t *testing.T) { func Test_Int8_All(t *testing.T) { gtest.C(t, func(t *gtest.T) { - var i interface{} = nil - t.Assert(gconv.Int8(i), int8(0)) + var any interface{} = nil + t.Assert(gconv.Int8(any), int8(0)) t.AssertEQ(gconv.Int8(false), int8(0)) t.AssertEQ(gconv.Int8(nil), int8(0)) t.AssertEQ(gconv.Int8(0), int8(0)) @@ -141,8 +141,8 @@ func Test_Int8_All(t *testing.T) { func Test_Int16_All(t *testing.T) { gtest.C(t, func(t *gtest.T) { - var i interface{} = nil - t.Assert(gconv.Int16(i), int16(0)) + var any interface{} = nil + t.Assert(gconv.Int16(any), int16(0)) t.AssertEQ(gconv.Int16(false), int16(0)) t.AssertEQ(gconv.Int16(nil), int16(0)) t.AssertEQ(gconv.Int16(0), int16(0)) @@ -175,8 +175,8 @@ func Test_Int16_All(t *testing.T) { func Test_Int32_All(t *testing.T) { gtest.C(t, func(t *gtest.T) { - var i interface{} = nil - t.Assert(gconv.Int32(i), int32(0)) + var any interface{} = nil + t.Assert(gconv.Int32(any), int32(0)) t.AssertEQ(gconv.Int32(false), int32(0)) t.AssertEQ(gconv.Int32(nil), int32(0)) t.AssertEQ(gconv.Int32(0), int32(0)) @@ -209,11 +209,11 @@ func Test_Int32_All(t *testing.T) { func Test_Int64_All(t *testing.T) { gtest.C(t, func(t *gtest.T) { - var i interface{} = nil + var any interface{} = nil t.AssertEQ(gconv.Int64("0x00e"), int64(14)) t.Assert(gconv.Int64("022"), int64(18)) - t.Assert(gconv.Int64(i), int64(0)) + t.Assert(gconv.Int64(any), int64(0)) t.Assert(gconv.Int64(true), 1) t.Assert(gconv.Int64("1"), int64(1)) t.Assert(gconv.Int64("0"), int64(0)) @@ -263,8 +263,8 @@ func Test_Int64_All(t *testing.T) { func Test_Uint_All(t *testing.T) { gtest.C(t, func(t *gtest.T) { - var i interface{} = nil - t.AssertEQ(gconv.Uint(i), uint(0)) + var any interface{} = nil + t.AssertEQ(gconv.Uint(any), uint(0)) t.AssertEQ(gconv.Uint(false), uint(0)) t.AssertEQ(gconv.Uint(nil), uint(0)) t.Assert(gconv.Uint(nil), uint(0)) @@ -298,8 +298,8 @@ func Test_Uint_All(t *testing.T) { func Test_Uint8_All(t *testing.T) { gtest.C(t, func(t *gtest.T) { - var i interface{} = nil - t.Assert(gconv.Uint8(i), uint8(0)) + var any interface{} = nil + t.Assert(gconv.Uint8(any), uint8(0)) t.AssertEQ(gconv.Uint8(uint8(1)), uint8(1)) t.AssertEQ(gconv.Uint8(false), uint8(0)) t.AssertEQ(gconv.Uint8(nil), uint8(0)) @@ -333,8 +333,8 @@ func Test_Uint8_All(t *testing.T) { func Test_Uint16_All(t *testing.T) { gtest.C(t, func(t *gtest.T) { - var i interface{} = nil - t.Assert(gconv.Uint16(i), uint16(0)) + var any interface{} = nil + t.Assert(gconv.Uint16(any), uint16(0)) t.AssertEQ(gconv.Uint16(uint16(1)), uint16(1)) t.AssertEQ(gconv.Uint16(false), uint16(0)) t.AssertEQ(gconv.Uint16(nil), uint16(0)) @@ -368,8 +368,8 @@ func Test_Uint16_All(t *testing.T) { func Test_Uint32_All(t *testing.T) { gtest.C(t, func(t *gtest.T) { - var i interface{} = nil - t.Assert(gconv.Uint32(i), uint32(0)) + var any interface{} = nil + t.Assert(gconv.Uint32(any), uint32(0)) t.AssertEQ(gconv.Uint32(uint32(1)), uint32(1)) t.AssertEQ(gconv.Uint32(false), uint32(0)) t.AssertEQ(gconv.Uint32(nil), uint32(0)) @@ -403,11 +403,11 @@ func Test_Uint32_All(t *testing.T) { func Test_Uint64_All(t *testing.T) { gtest.C(t, func(t *gtest.T) { - var i interface{} = nil + var any interface{} = nil t.AssertEQ(gconv.Uint64("0x00e"), uint64(14)) t.Assert(gconv.Uint64("022"), uint64(18)) - t.AssertEQ(gconv.Uint64(i), uint64(0)) + t.AssertEQ(gconv.Uint64(any), uint64(0)) t.AssertEQ(gconv.Uint64(true), uint64(1)) t.Assert(gconv.Uint64("1"), int64(1)) t.Assert(gconv.Uint64("0"), uint64(0)) @@ -457,8 +457,8 @@ func Test_Uint64_All(t *testing.T) { func Test_Float32_All(t *testing.T) { gtest.C(t, func(t *gtest.T) { - var i interface{} = nil - t.Assert(gconv.Float32(i), float32(0)) + var any interface{} = nil + t.Assert(gconv.Float32(any), float32(0)) t.AssertEQ(gconv.Float32(false), float32(0)) t.AssertEQ(gconv.Float32(nil), float32(0)) t.AssertEQ(gconv.Float32(0), float32(0)) @@ -491,8 +491,8 @@ func Test_Float32_All(t *testing.T) { func Test_Float64_All(t *testing.T) { gtest.C(t, func(t *gtest.T) { - var i interface{} = nil - t.Assert(gconv.Float64(i), float64(0)) + var any interface{} = nil + t.Assert(gconv.Float64(any), float64(0)) t.AssertEQ(gconv.Float64(false), float64(0)) t.AssertEQ(gconv.Float64(nil), float64(0)) t.AssertEQ(gconv.Float64(0), float64(0)) @@ -527,8 +527,8 @@ func Test_String_All(t *testing.T) { gtest.C(t, func(t *gtest.T) { var s []rune t.AssertEQ(gconv.String(s), "") - var i interface{} = nil - t.AssertEQ(gconv.String(i), "") + var any interface{} = nil + t.AssertEQ(gconv.String(any), "") t.AssertEQ(gconv.String("1"), "1") t.AssertEQ(gconv.String("0"), string("0")) t.Assert(gconv.String("X"), string("X")) @@ -615,8 +615,8 @@ func Test_Byte_All(t *testing.T) { func Test_Convert_All(t *testing.T) { gtest.C(t, func(t *gtest.T) { - var i interface{} = nil - t.AssertEQ(gconv.Convert(i, "string"), "") + var any interface{} = nil + t.AssertEQ(gconv.Convert(any, "string"), "") t.AssertEQ(gconv.Convert("1", "string"), "1") t.Assert(gconv.Convert(int64(1), "int64"), int64(1)) t.Assert(gconv.Convert(int(0), "int"), int(0)) diff --git a/util/gconv/gconv_z_unit_bool_test.go b/util/gconv/gconv_z_unit_bool_test.go index 7e0c97a5e..cfe2b143e 100644 --- a/util/gconv/gconv_z_unit_bool_test.go +++ b/util/gconv/gconv_z_unit_bool_test.go @@ -18,8 +18,8 @@ type boolStruct struct { func Test_Bool(t *testing.T) { gtest.C(t, func(t *gtest.T) { - var i interface{} = nil - t.AssertEQ(gconv.Bool(i), false) + var any interface{} = nil + t.AssertEQ(gconv.Bool(any), false) t.AssertEQ(gconv.Bool(false), false) t.AssertEQ(gconv.Bool(nil), false) t.AssertEQ(gconv.Bool(0), false) diff --git a/util/gconv/gconv_z_unit_slice_test.go b/util/gconv/gconv_z_unit_slice_test.go index 42c8bdec3..062b6fc17 100644 --- a/util/gconv/gconv_z_unit_slice_test.go +++ b/util/gconv/gconv_z_unit_slice_test.go @@ -7,6 +7,7 @@ package gconv_test import ( + "github.com/gogf/gf/container/gvar" "testing" "github.com/gogf/gf/frame/g" @@ -23,6 +24,13 @@ func Test_Slice(t *testing.T) { t.AssertEQ(gconv.Floats(value), []float64{123.456}) t.AssertEQ(gconv.Interfaces(value), []interface{}{123.456}) }) + gtest.C(t, func(t *gtest.T) { + s := []*gvar.Var{ + gvar.New(1), + gvar.New(2), + } + t.AssertEQ(gconv.SliceInt64(s), []int64{1, 2}) + }) } func Test_Slice_Empty(t *testing.T) {