GoFrame类型转换详解

基本类型:

示例:

Go 复制代码
package main

import (
    "fmt"
    "github.com/gogf/gf/v2/util/gconv"
)



func main() {
    i := 123.456
    intValue := gconv.Int(i)
    fmt.Println(intValue)
    uintValue := gconv.Uint(i)
    fmt.Println(uintValue)
    floatValue := gconv.Float32(i)
    fmt.Println(floatValue)
    boolValue := gconv.Bool(i)
    fmt.Println(boolValue)
    strValue := gconv.String(i)
    fmt.Println(strValue)
    byteValue := gconv.Bytes(i)
    fmt.Println(byteValue)
    intsValue := gconv.Ints(i)
    fmt.Println(intsValue)
    floatsValue := gconv.Floats(i)
    fmt.Println(floatsValue)
    interFacValue := gconv.Interfaces(i)
    fmt.Println(interFacValue)
}

执行结果:

从上面结果可以看到把123.123数字转换为了不同的格式.

gconv.Int()方法:

Go 复制代码
func Int(anyInput any) int {
    v, _ := defaultConverter.Int(anyInput)
    return v
}

这个方法接收了一个any参数.然后把这个参数又传给了defaultConverter的Int()方法.源码如下.

Go 复制代码
func (c *Converter) Int(anyInput any) (int, error) {
    if v, ok := anyInput.(int); ok {
       return v, nil
    }
    v, err := c.Int64(anyInput)
    if err != nil {
       return 0, err
    }
    return int(v), nil
}

Int64方法源码如下:

Go 复制代码
func (c *Converter) Int64(anyInput any) (int64, error) {
    if empty.IsNil(anyInput) {
       return 0, nil
    }
    if v, ok := anyInput.(int64); ok {
       return v, nil
    }
    rv := reflect.ValueOf(anyInput)
    switch rv.Kind() {
    case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
       return rv.Int(), nil
    case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
       return int64(rv.Uint()), nil
    case reflect.Uintptr:
       return int64(rv.Uint()), nil
    case reflect.Float32, reflect.Float64:
       return int64(rv.Float()), nil
    case reflect.Bool:
       if rv.Bool() {
          return 1, nil
       }
       return 0, nil
    case reflect.Pointer:
       if rv.IsNil() {
          return 0, nil
       }
       if f, ok := anyInput.(localinterface.IInt64); ok {
          return f.Int64(), nil
       }
       return c.Int64(rv.Elem().Interface())
    case reflect.Slice:
       // TODO: It might panic here for these types.
       if rv.Type().Elem().Kind() == reflect.Uint8 {
          return gbinary.DecodeToInt64(rv.Bytes()), nil
       }
    case reflect.String:
       var (
          s       = rv.String()
          isMinus = false
       )
       if len(s) > 0 {
          switch s[0] {
          case '-':
             isMinus = true
             s = s[1:]
          case '+':
             s = s[1:]
          }
       }
       // Hexadecimal.
       if len(s) > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X') {
          if v, e := strconv.ParseInt(s[2:], 16, 64); e == nil {
             if isMinus {
                return -v, nil
             }
             return v, nil
          }
       }
       // Decimal.
       if v, e := strconv.ParseInt(s, 10, 64); e == nil {
          if isMinus {
             return -v, nil
          }
          return v, nil
       }
       // Float64.
       valueInt64, err := c.Float64(s)
       if err != nil {
          return 0, err
       }
       if math.IsNaN(valueInt64) {
          return 0, nil
       } else {
          if isMinus {
             return -int64(valueInt64), nil
          }
          return int64(valueInt64), nil
       }
    default:
       if f, ok := anyInput.(localinterface.IInt64); ok {
          return f.Int64(), nil
       }
    }
    return 0, gerror.NewCodef(
       gcode.CodeInvalidParameter,
       `unsupport value type for converting to int64: %v`,
       reflect.TypeOf(anyInput),
    )
}

gconv.Uint()方法:

Go 复制代码
func Uint(anyInput any) uint {
    v, _ := defaultConverter.Uint(anyInput)
    return v
}

这个方法接收了一个any参数.然后把这个参数又传给了defaultConverter的Uint()方法.源码如下.

Go 复制代码
func (c *Converter) Uint(anyInput any) (uint, error) {
    if empty.IsNil(anyInput) {
       return 0, nil
    }
    if v, ok := anyInput.(uint); ok {
       return v, nil
    }
    v, err := c.Uint64(anyInput)
    return uint(v), err
}

Uint64源码如下:

Go 复制代码
func (c *Converter) Uint64(anyInput any) (uint64, error) {
    if empty.IsNil(anyInput) {
       return 0, nil
    }
    if v, ok := anyInput.(uint64); ok {
       return v, nil
    }
    rv := reflect.ValueOf(anyInput)
    switch rv.Kind() {
    case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
       val := rv.Int()
       if val < 0 {
          return uint64(val), gerror.NewCodef(
             gcode.CodeInvalidParameter,
             `cannot convert negative value "%d" to uint64`,
             val,
          )
       }
       return uint64(val), nil
    case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
       return rv.Uint(), nil
    case reflect.Uintptr:
       return rv.Uint(), nil
    case reflect.Float32, reflect.Float64:
       val := rv.Float()
       if val < 0 {
          return uint64(val), gerror.NewCodef(
             gcode.CodeInvalidParameter,
             `cannot convert negative value "%f" to uint64`,
             val,
          )
       }
       return uint64(val), nil
    case reflect.Bool:
       if rv.Bool() {
          return 1, nil
       }
       return 0, nil
    case reflect.Pointer:
       if rv.IsNil() {
          return 0, nil
       }
       if f, ok := anyInput.(localinterface.IUint64); ok {
          return f.Uint64(), nil
       }
       return c.Uint64(rv.Elem().Interface())
    case reflect.Slice:
       if rv.Type().Elem().Kind() == reflect.Uint8 {
          return gbinary.DecodeToUint64(rv.Bytes()), nil
       }
       return 0, gerror.NewCodef(
          gcode.CodeInvalidParameter,
          `unsupport slice type "%s" for converting to uint64`,
          rv.Type().String(),
       )
    case reflect.String:
       var s = rv.String()
       // Hexadecimal
       if len(s) > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X') {
          v, err := strconv.ParseUint(s[2:], 16, 64)
          if err == nil {
             return v, nil
          }
          return 0, gerror.WrapCodef(
             gcode.CodeInvalidParameter,
             err,
             `cannot convert hexadecimal string "%s" to uint64`,
             s,
          )
       }
       // Decimal
       if v, err := strconv.ParseUint(s, 10, 64); err == nil {
          return v, nil
       }
       // Float64
       if v, err := c.Float64(anyInput); err == nil {
          if math.IsNaN(v) {
             return 0, nil
          }
          return uint64(v), nil
       }
    default:
       if f, ok := anyInput.(localinterface.IUint64); ok {
          return f.Uint64(), nil
       }
    }
    return 0, gerror.NewCodef(
       gcode.CodeInvalidParameter,
       `unsupport value type "%s" for converting to uint64`,
       reflect.TypeOf(anyInput).String(),
    )
}

这个方法是上面的方法类似.唯一不同的是.

gconv.Float32()方法:

Go 复制代码
func Float32(anyInput any) float32 {
    v, _ := defaultConverter.Float32(anyInput)
    return v
}

这个方法接收了一个any参数.然后把这个参数又传给了defaultConverter的Float32()方法.源码如下.

Go 复制代码
func (c *Converter) Float32(anyInput any) (float32, error) {
    if empty.IsNil(anyInput) {
       return 0, nil
    }
    switch value := anyInput.(type) {
    case float32:
       return value, nil
    case float64:
       return float32(value), nil
    case []byte:
       // TODO: It might panic here for these types.
       return gbinary.DecodeToFloat32(value), nil
    default:
       rv := reflect.ValueOf(anyInput)
       switch rv.Kind() {
       case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
          return float32(rv.Int()), nil
       case reflect.Uintptr, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
          return float32(rv.Uint()), nil
       case reflect.Float32, reflect.Float64:
          return float32(rv.Float()), nil
       case reflect.Bool:
          if rv.Bool() {
             return 1, nil
          }
          return 0, nil
       case reflect.String:
          f, err := strconv.ParseFloat(rv.String(), 32)
          if err != nil {
             return 0, gerror.WrapCodef(
                gcode.CodeInvalidParameter, err, "converting string to float32 failed for: %v", anyInput,
             )
          }
          return float32(f), nil
       case reflect.Pointer:
          if rv.IsNil() {
             return 0, nil
          }
          if f, ok := value.(localinterface.IFloat32); ok {
             return f.Float32(), nil
          }
          return c.Float32(rv.Elem().Interface())
       default:
          if f, ok := value.(localinterface.IFloat32); ok {
             return f.Float32(), nil
          }
          s, err := c.String(anyInput)
          if err != nil {
             return 0, err
          }
          v, err := strconv.ParseFloat(s, 32)
          if err != nil {
             return 0, gerror.WrapCodef(
                gcode.CodeInvalidParameter, err, "converting string to float32 failed for: %v", anyInput,
             )
          }
          return float32(v), nil
       }
    }
}

gconv.Bool()方法:

Go 复制代码
func Bool(anyInput any) bool {
    v, _ := defaultConverter.Bool(anyInput)
    return v
}

这个方法接收了一个any参数.然后把这个参数又传给了defaultConverter的Bool()方法.源码如下.

Go 复制代码
func (c *Converter) Bool(anyInput any) (bool, error) {
    if empty.IsNil(anyInput) {
       return false, nil
    }
    switch value := anyInput.(type) {
    case bool:
       return value, nil
    case []byte:
       if parsed, err := strconv.ParseBool(string(value)); err == nil {
          return parsed, nil
       }
       if _, ok := emptyStringMap[strings.ToLower(string(value))]; ok {
          return false, nil
       }
       return true, nil
    case string:
       if parsed, err := strconv.ParseBool(value); err == nil {
          return parsed, nil
       }
       if _, ok := emptyStringMap[strings.ToLower(value)]; ok {
          return false, nil
       }
       return true, nil
    default:
       if f, ok := value.(localinterface.IBool); ok {
          return f.Bool(), nil
       }
       rv := reflect.ValueOf(anyInput)
       switch rv.Kind() {
       case reflect.Pointer:
          if rv.IsNil() {
             return false, nil
          }
          if rv.Type().Elem().Kind() == reflect.Bool {
             return rv.Elem().Bool(), nil
          }
          return c.Bool(rv.Elem().Interface())
       case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
          return rv.Int() != 0, nil
       case reflect.Uintptr, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
          return rv.Uint() != 0, nil
       case reflect.Float32, reflect.Float64:
          return rv.Float() != 0, nil
       case reflect.Bool:
          return rv.Bool(), nil
       // TODO:(Map,Array,Slice,Struct) It might panic here for these types.
       case reflect.Map, reflect.Array:
          fallthrough
       case reflect.Slice:
          return rv.Len() != 0, nil
       case reflect.Struct:
          return true, nil
       default:
          s, err := c.String(anyInput)
          if err != nil {
             return false, err
          }
          if _, ok := emptyStringMap[strings.ToLower(s)]; ok {
             return false, nil
          }
          return true, nil
       }
    }
}

通过上面提前定义好的字符串来判断是true还是false.

gconv.String()方法:

Go 复制代码
func String(anyInput any) string {
    v, _ := defaultConverter.String(anyInput)
    return v
}

这个方法接收了一个any参数.然后把这个参数又传给了defaultConverter的Int()方法.源码如下.

Go 复制代码
func (c *Converter) String(anyInput any) (string, error) {
    if empty.IsNil(anyInput) {
       return "", nil
    }
    switch value := anyInput.(type) {
    case int:
       return strconv.Itoa(value), nil
    case int8:
       return strconv.Itoa(int(value)), nil
    case int16:
       return strconv.Itoa(int(value)), nil
    case int32:
       return strconv.Itoa(int(value)), nil
    case int64:
       return strconv.FormatInt(value, 10), nil
    case uint:
       return strconv.FormatUint(uint64(value), 10), nil
    case uint8:
       return strconv.FormatUint(uint64(value), 10), nil
    case uint16:
       return strconv.FormatUint(uint64(value), 10), nil
    case uint32:
       return strconv.FormatUint(uint64(value), 10), nil
    case uint64:
       return strconv.FormatUint(value, 10), nil
    case float32:
       return strconv.FormatFloat(float64(value), 'f', -1, 32), nil
    case float64:
       return strconv.FormatFloat(value, 'f', -1, 64), nil
    case bool:
       return strconv.FormatBool(value), nil
    case string:
       return value, nil
    case []byte:
       return string(value), nil
    case complex64, complex128:
       return fmt.Sprintf("%v", value), nil
    case time.Time:
       if value.IsZero() {
          return "", nil
       }
       return value.String(), nil
    case *time.Time:
       if value == nil {
          return "", nil
       }
       return value.String(), nil
    case gtime.Time:
       if value.IsZero() {
          return "", nil
       }
       return value.String(), nil
    case *gtime.Time:
       if value == nil {
          return "", nil
       }
       return value.String(), nil
    default:
       if f, ok := value.(localinterface.IString); ok {
          // If the variable implements the String() interface,
          // then use that interface to perform the conversion
          return f.String(), nil
       }
       if f, ok := value.(localinterface.IError); ok {
          // If the variable implements the Error() interface,
          // then use that interface to perform the conversion
          return f.Error(), nil
       }
       // Reflect checks.
       var (
          rv   = reflect.ValueOf(value)
          kind = rv.Kind()
       )
       switch kind {
       case
          reflect.Chan,
          reflect.Map,
          reflect.Slice,
          reflect.Func,
          reflect.Interface,
          reflect.UnsafePointer:
          if rv.IsNil() {
             return "", nil
          }
       case reflect.String:
          return rv.String(), nil
       case reflect.Pointer:
          if rv.IsNil() {
             return "", nil
          }
          return c.String(rv.Elem().Interface())
       case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
          return strconv.FormatInt(rv.Int(), 10), nil
       case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
          return strconv.FormatUint(rv.Uint(), 10), nil
       case reflect.Uintptr:
          return strconv.FormatUint(rv.Uint(), 10), nil
       case reflect.Float32, reflect.Float64:
          return strconv.FormatFloat(rv.Float(), 'f', -1, 64), nil
       case reflect.Bool:
          return strconv.FormatBool(rv.Bool()), nil
       default:
       }
       // Finally, we use json.Marshal to convert.
       jsonContent, err := json.Marshal(value)
       if err != nil {
          return fmt.Sprint(value), gerror.WrapCodef(
             gcode.CodeInvalidParameter, err, "error marshaling value to JSON for: %v", value,
          )
       }
       return string(jsonContent), nil
    }

gconv.Bytes()方法:

Go 复制代码
func Bytes(anyInput any) []byte {
    v, _ := defaultConverter.Bytes(anyInput)
    return v
}

这个方法接收了一个any参数.然后把这个参数又传给了defaultConverter的Bytes()方法.源码如下.

Go 复制代码
func (c *Converter) Bytes(anyInput any) ([]byte, error) {
    if empty.IsNil(anyInput) {
       return nil, nil
    }
    switch value := anyInput.(type) {
    case string:
       return []byte(value), nil

    case []byte:
       return value, nil

    default:
       if f, ok := value.(localinterface.IBytes); ok {
          return f.Bytes(), nil
       }
       originValueAndKind := reflection.OriginValueAndKind(anyInput)
       switch originValueAndKind.OriginKind {
       case reflect.Map:
          bytes, err := json.Marshal(anyInput)
          if err != nil {
             return nil, err
          }
          return bytes, nil

       case reflect.Array, reflect.Slice:
          var (
             ok    = true
             bytes = make([]byte, originValueAndKind.OriginValue.Len())
          )
          for i := range bytes {
             int32Value, err := c.Int32(originValueAndKind.OriginValue.Index(i).Interface())
             if err != nil {
                return nil, err
             }
             if int32Value < 0 || int32Value > math.MaxUint8 {
                ok = false
                break
             }
             bytes[i] = byte(int32Value)
          }
          if ok {
             return bytes, nil
          }
       default:
       }
       return gbinary.Encode(anyInput), nil
    }
}

gconv.Ints()方法:

Go 复制代码
func Ints(anyInput any) []int {
    result, _ := defaultConverter.SliceInt(anyInput, SliceOption{
       ContinueOnError: true,
    })
    return result
}

这个方法接收了一个any参数.然后把这个参数又传给了defaultConverter的SliceInt()方法.源码如下.

Go 复制代码
func (c *Converter) SliceInt(anyInput any, option ...SliceOption) ([]int, error) {
    if empty.IsNil(anyInput) {
       return nil, nil
    }
    var (
       err         error
       ii          int
       array       []int = nil
       sliceOption       = c.getSliceOption(option...)
    )
    switch value := anyInput.(type) {
    case []string:
       array = make([]int, len(value))
       for k, v := range value {
          ii, err = c.Int(v)
          if err != nil && !sliceOption.ContinueOnError {
             return nil, err
          }
          array[k] = ii
       }
    case []int:
       array = value
    case []int8:
       array = make([]int, len(value))
       for k, v := range value {
          array[k] = int(v)
       }
    case []int16:
       array = make([]int, len(value))
       for k, v := range value {
          array[k] = int(v)
       }
    case []int32:
       array = make([]int, len(value))
       for k, v := range value {
          array[k] = int(v)
       }
    case []int64:
       array = make([]int, len(value))
       for k, v := range value {
          array[k] = int(v)
       }
    case []uint:
       array = make([]int, len(value))
       for k, v := range value {
          array[k] = int(v)
       }
    case []uint8:
       if json.Valid(value) {
          if err = json.UnmarshalUseNumber(value, &array); array != nil {
             return array, err
          }
       }
       array = make([]int, len(value))
       for k, v := range value {
          array[k] = int(v)
       }
    case string:
       byteValue := []byte(value)
       if json.Valid(byteValue) {
          if err = json.UnmarshalUseNumber(byteValue, &array); array != nil {
             return array, err
          }
       }
       if value == "" {
          return []int{}, err
       }
       if utils.IsNumeric(value) {
          ii, err = c.Int(value)
          if err != nil && !sliceOption.ContinueOnError {
             return nil, err
          }
          return []int{ii}, err
       }
    case []uint16:
       array = make([]int, len(value))
       for k, v := range value {
          array[k] = int(v)
       }
    case []uint32:
       array = make([]int, len(value))
       for k, v := range value {
          array[k] = int(v)
       }
    case []uint64:
       array = make([]int, len(value))
       for k, v := range value {
          array[k] = int(v)
       }
    case []bool:
       array = make([]int, len(value))
       for k, v := range value {
          if v {
             array[k] = 1
          } else {
             array[k] = 0
          }
       }
    case []float32:
       array = make([]int, len(value))
       for k, v := range value {
          ii, err = c.Int(v)
          if err != nil && !sliceOption.ContinueOnError {
             return nil, err
          }
          array[k] = ii
       }
    case []float64:
       array = make([]int, len(value))
       for k, v := range value {
          ii, err = c.Int(v)
          if err != nil && !sliceOption.ContinueOnError {
             return nil, err
          }
          array[k] = ii
       }
    case []any:
       array = make([]int, len(value))
       for k, v := range value {
          ii, err = c.Int(v)
          if err != nil && !sliceOption.ContinueOnError {
             return nil, err
          }
          array[k] = ii
       }
    case [][]byte:
       array = make([]int, len(value))
       for k, v := range value {
          ii, err = c.Int(v)
          if err != nil && !sliceOption.ContinueOnError {
             return nil, err
          }
          array[k] = ii
       }
    }
    if array != nil {
       return array, err
    }
    if v, ok := anyInput.(localinterface.IInts); ok {
       return v.Ints(), err
    }
    if v, ok := anyInput.(localinterface.IInterfaces); ok {
       return c.SliceInt(v.Interfaces(), option...)
    }
    // Not a common type, it then uses reflection for conversion.
    originValueAndKind := reflection.OriginValueAndKind(anyInput)
    switch originValueAndKind.OriginKind {
    case reflect.Slice, reflect.Array:
       var (
          length = originValueAndKind.OriginValue.Len()
          slice  = make([]int, length)
       )
       for i := 0; i < length; i++ {
          ii, err = c.Int(originValueAndKind.OriginValue.Index(i).Interface())
          if err != nil && !sliceOption.ContinueOnError {
             return nil, err
          }
          slice[i] = ii
       }
       return slice, err

    default:
       if originValueAndKind.OriginValue.IsZero() {
          return []int{}, err
       }
       ii, err = c.Int(anyInput)
       if err != nil && !sliceOption.ContinueOnError {
          return nil, err
       }
       return []int{ii}, err
    }
}

gconv.Floats()方法:

Go 复制代码
func Floats(anyInput any) []float64 {
    return Float64s(anyInput)
}

Floats()方法如下.

Go 复制代码
func Float64s(anyInput any) []float64 {
    result, _ := defaultConverter.SliceFloat64(anyInput, SliceOption{
       ContinueOnError: true,
    })
    return result
}

这个方法接收了一个any参数.然后把这个参数又传给了defaultConverter的SliceFloat64()方法.源码如下.

Go 复制代码
func (c *Converter) SliceFloat64(anyInput any, option ...SliceOption) ([]float64, error) {
    if empty.IsNil(anyInput) {
       return nil, nil
    }
    var (
       err         error
       f           float64
       array       []float64 = nil
       sliceOption           = c.getSliceOption(option...)
    )
    switch value := anyInput.(type) {
    case []string:
       array = make([]float64, len(value))
       for k, v := range value {
          f, err = c.Float64(v)
          if err != nil && !sliceOption.ContinueOnError {
             return nil, err
          }
          array[k] = f
       }
    case []int:
       array = make([]float64, len(value))
       for k, v := range value {
          f, err = c.Float64(v)
          if err != nil && !sliceOption.ContinueOnError {
             return nil, err
          }
          array[k] = f
       }
    case []int8:
       array = make([]float64, len(value))
       for k, v := range value {
          f, err = c.Float64(v)
          if err != nil && !sliceOption.ContinueOnError {
             return nil, err
          }
          array[k] = f
       }
    case []int16:
       array = make([]float64, len(value))
       for k, v := range value {
          f, err = c.Float64(v)
          if err != nil && !sliceOption.ContinueOnError {
             return nil, err
          }
          array[k] = f
       }
    case []int32:
       array = make([]float64, len(value))
       for k, v := range value {
          f, err = c.Float64(v)
          if err != nil && !sliceOption.ContinueOnError {
             return nil, err
          }
          array[k] = f
       }
    case []int64:
       array = make([]float64, len(value))
       for k, v := range value {
          f, err = c.Float64(v)
          if err != nil && !sliceOption.ContinueOnError {
             return nil, err
          }
          array[k] = f
       }
    case []uint:
       array = make([]float64, len(value))
       for k, v := range value {
          f, err = c.Float64(v)
          if err != nil && !sliceOption.ContinueOnError {
             return nil, err
          }
          array[k] = f
       }
    case []uint8:
       if json.Valid(value) {
          if err = json.UnmarshalUseNumber(value, &array); array != nil {
             return array, err
          }
       }
       array = make([]float64, len(value))
       for k, v := range value {
          f, err = c.Float64(v)
          if err != nil && !sliceOption.ContinueOnError {
             return nil, err
          }
          array[k] = f
       }
    case string:
       byteValue := []byte(value)
       if json.Valid(byteValue) {
          if err = json.UnmarshalUseNumber(byteValue, &array); array != nil {
             return array, err
          }
       }
       if value == "" {
          return []float64{}, err
       }
       if utils.IsNumeric(value) {
          f, err = c.Float64(value)
          if err != nil && !sliceOption.ContinueOnError {
             return nil, err
          }
          return []float64{f}, err
       }
    case []uint16:
       array = make([]float64, len(value))
       for k, v := range value {
          f, err = c.Float64(v)
          if err != nil && !sliceOption.ContinueOnError {
             return nil, err
          }
          array[k] = f
       }
    case []uint32:
       array = make([]float64, len(value))
       for k, v := range value {
          f, err = c.Float64(v)
          if err != nil && !sliceOption.ContinueOnError {
             return nil, err
          }
          array[k] = f
       }
    case []uint64:
       array = make([]float64, len(value))
       for k, v := range value {
          f, err = c.Float64(v)
          if err != nil && !sliceOption.ContinueOnError {
             return nil, err
          }
          array[k] = f
       }
    case []bool:
       array = make([]float64, len(value))
       for k, v := range value {
          f, err = c.Float64(v)
          if err != nil && !sliceOption.ContinueOnError {
             return nil, err
          }
          array[k] = f
       }
    case []float32:
       array = make([]float64, len(value))
       for k, v := range value {
          f, err = c.Float64(v)
          if err != nil && !sliceOption.ContinueOnError {
             return nil, err
          }
          array[k] = f
       }
    case []float64:
       array = value
    case []any:
       array = make([]float64, len(value))
       for k, v := range value {
          f, err = c.Float64(v)
          if err != nil && !sliceOption.ContinueOnError {
             return nil, err
          }
          array[k] = f
       }
    }
    if array != nil {
       return array, err
    }
    if v, ok := anyInput.(localinterface.IFloats); ok {
       return v.Floats(), err
    }
    if v, ok := anyInput.(localinterface.IInterfaces); ok {
       return c.SliceFloat64(v.Interfaces(), option...)
    }
    // Not a common type, it then uses reflection for conversion.
    originValueAndKind := reflection.OriginValueAndKind(anyInput)
    switch originValueAndKind.OriginKind {
    case reflect.Slice, reflect.Array:
       var (
          length = originValueAndKind.OriginValue.Len()
          slice  = make([]float64, length)
       )
       for i := 0; i < length; i++ {
          f, err = c.Float64(originValueAndKind.OriginValue.Index(i).Interface())
          if err != nil && !sliceOption.ContinueOnError {
             return nil, err
          }
          slice[i] = f
       }
       return slice, err

    default:
       if originValueAndKind.OriginValue.IsZero() {
          return []float64{}, err
       }
       f, err = c.Float64(anyInput)
       if err != nil && !sliceOption.ContinueOnError {
          return nil, err
       }
       return []float64{f}, err
    }
}

这个方法和上面Ints方法类似.可以参考上面的.

gconv.Interfaces()方法:

Go 复制代码
func Interfaces(anyInput any) []any {
    result, _ := defaultConverter.SliceAny(anyInput, SliceOption{
       ContinueOnError: true,
    })
    return result
}

这个方法接收了一个any参数.然后把这个参数又传给了defaultConverter的SliceAny()方法.源码如下.

Go 复制代码
func (c *Converter) SliceAny(anyInput any, _ ...SliceOption) ([]any, error) {
    if empty.IsNil(anyInput) {
       return nil, nil
    }
    var (
       err   error
       array []any
    )
    switch value := anyInput.(type) {
    case []any:
       array = value
    case []string:
       array = make([]any, len(value))
       for k, v := range value {
          array[k] = v
       }
    case []int:
       array = make([]any, len(value))
       for k, v := range value {
          array[k] = v
       }
    case []int8:
       array = make([]any, len(value))
       for k, v := range value {
          array[k] = v
       }
    case []int16:
       array = make([]any, len(value))
       for k, v := range value {
          array[k] = v
       }
    case []int32:
       array = make([]any, len(value))
       for k, v := range value {
          array[k] = v
       }
    case []int64:
       array = make([]any, len(value))
       for k, v := range value {
          array[k] = v
       }
    case []uint:
       array = make([]any, len(value))
       for k, v := range value {
          array[k] = v
       }
    case []uint8:
       if json.Valid(value) {
          if err = json.UnmarshalUseNumber(value, &array); array != nil {
             return array, err
          }
       }
       array = make([]any, len(value))
       for k, v := range value {
          array[k] = v
       }
    case string:
       byteValue := []byte(value)
       if json.Valid(byteValue) {
          if err = json.UnmarshalUseNumber(byteValue, &array); array != nil {
             return array, err
          }
       }

    case []uint16:
       array = make([]any, len(value))
       for k, v := range value {
          array[k] = v
       }
    case []uint32:
       for _, v := range value {
          array = append(array, v)
       }
    case []uint64:
       array = make([]any, len(value))
       for k, v := range value {
          array[k] = v
       }
    case []bool:
       array = make([]any, len(value))
       for k, v := range value {
          array[k] = v
       }
    case []float32:
       array = make([]any, len(value))
       for k, v := range value {
          array[k] = v
       }
    case []float64:
       array = make([]any, len(value))
       for k, v := range value {
          array[k] = v
       }
    }
    if array != nil {
       return array, err
    }
    if v, ok := anyInput.(localinterface.IInterfaces); ok {
       return v.Interfaces(), err
    }

    // Not a common type, it then uses reflection for conversion.
    originValueAndKind := reflection.OriginValueAndKind(anyInput)
    switch originValueAndKind.OriginKind {
    case reflect.Slice, reflect.Array:
       var (
          length = originValueAndKind.OriginValue.Len()
          slice  = make([]any, length)
       )
       for i := 0; i < length; i++ {
          slice[i] = originValueAndKind.OriginValue.Index(i).Interface()
       }
       return slice, err

    default:
       return []any{anyInput}, err
    }
}

这个方法也和上面的类似.可以参考上面的.

语雀地址https://www.yuque.com/itbosunmianyi/xg8vfe?

《Go.》 密码:xbkk 欢迎大家访问.提意见.

相关推荐
m0_502724954 小时前
golang 、java、c++、javascript 语言switch case异同
java·javascript·c++·golang
jieyucx6 小时前
Go 语言进阶:结构体指针、new 关键字与匿名结构体/成员详解
开发语言·后端·golang·结构体
赛特·亮7 小时前
利用WTAPI(WeChatapi)-robot-go 项目解析与实战指南
微信·面试·golang
Achou.Wang8 小时前
Selecting channels:Go 并发里的“多路开关”
服务器·数据库·golang
Generalzy8 小时前
为什么 Go 的注释,能控制编译器?
java·python·golang
Wy_编程8 小时前
go语言面向对象和异常处理
开发语言·后端·golang
Wy_编程17 小时前
go语言中的结构体
开发语言·后端·golang
lolo大魔王19 小时前
Go 后端实战|Gin + GORM V2 + MySQL 企业级 API 项目开发(完整版)
mysql·golang·gin
XMYX-019 小时前
28 - Go JSON 数据操作
开发语言·golang·json