improve package gconv for slice converting

This commit is contained in:
jianchenma
2021-02-05 14:44:20 +08:00
parent fefde4c290
commit 72251b880a
12 changed files with 496 additions and 337 deletions

View File

@ -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()

View File

@ -48,281 +48,281 @@ var (
// Convert converts the variable <i> to the type <t>, the type <t> is specified by string.
// The optional parameter <params> 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 <i> 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 <i> 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 <i> 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 <i> 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 <i> 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 <i> to bool.
// It returns false if <i> 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 <i> 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 <i> 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 <i> 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 <i> 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 <i> 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 <i> 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 <i> 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 <i> 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 <i> 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 <i> 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 <i> 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 <i> 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
}
}

View File

@ -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.

View File

@ -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 <i> 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

View File

@ -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 <i> to []float64.
func Floats(i interface{}) []float64 {
return Float64s(i)
func Floats(any interface{}) []float64 {
return Float64s(any)
}
// Float32s converts <i> 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 <i> 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

View File

@ -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 <i> 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 <i> 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 <i> 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
}

View File

@ -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 <i> 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

View File

@ -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 <i> 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 <i> 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 <i> 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

View File

@ -14,14 +14,14 @@ import (
)
// Time converts <i> 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 <i> to time.Duration.
// If <i> is string, then it uses time.ParseDuration to convert it.
// If <i> is numeric, then it converts <i> 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 <i> to *gtime.Time.
// The parameter <format> can be used to specify the format of <i>.
// If no <format> given, it converts <i> using gtime.NewFromTimeStamp if <i> is numeric,
// or using gtime.StrToTime if <i> 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()
}

View File

@ -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))

View File

@ -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)

View File

@ -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) {