简介

castcast

快速使用

先安装:

后使用:

package main

import (
'fmt'

'github.com/spf13/cast'
)

func main() {
// ToString
fmt.Println(cast.ToString('leedarjun')) // leedarjun
fmt.Println(cast.ToString(8)) // 8
fmt.Println(cast.ToString(8.31)) // 8.31
fmt.Println(cast.ToString([]byte('one time'))) // one time
fmt.Println(cast.ToString(nil)) // ''

var foo interface{} = 'one more time'
fmt.Println(cast.ToString(foo)) // one more time

// ToInt
fmt.Println(cast.ToInt(8)) // 8
fmt.Println(cast.ToInt(8.31)) // 8
fmt.Println(cast.ToInt('8')) // 8
fmt.Println(cast.ToInt(true)) // 1
fmt.Println(cast.ToInt(false)) // 0

var eight interface{} = 8
fmt.Println(cast.ToInt(eight)) // 8
fmt.Println(cast.ToInt(nil)) // 0
}
cast
nilstring'''nil'truestring'true'trueint1interface{}
niltime.Timetime.Durationmap[string]TypeType

高级转换

cast
ToTypeTypeTypeTypenilToTypeEerror
ToTypeToTypeEToTypecast.goToTypeEcaste.go
// cast/cast.go
func ToBool(i interface{}) bool {
v, _ := ToBoolE(i)
return v
}

// ToDuration casts an interface to a time.Duration type.
func ToDuration(i interface{}) time.Duration {
v, _ := ToDurationE(i)
return v
}
ToTypeEinterface{}
indirect
// cast/caste.go
func indirect(a interface{}) interface{} {
if a == nil {
return nil
}
if t := reflect.TypeOf(a); t.Kind() != reflect.Ptr {
// Avoid creating a reflect.Value if it's not a pointer.
return a
}
v := reflect.ValueOf(a)
for v.Kind() == reflect.Ptr && !v.IsNil() {
v = v.Elem()
}
return v.Interface()
}

所以,下面代码输出都是 8:

时间和时长转换

时间类型的转换代码如下:

func ToTimeE(i interface{}) (tim time.Time, err error) {
i = indirect(i)

switch v := i.(type) {
case time.Time:
return v, nil
case string:
return StringToDate(v)
case int:
return time.Unix(int64(v), 0), nil
case int64:
return time.Unix(v, 0), nil
case int32:
return time.Unix(int64(v), 0), nil
case uint:
return time.Unix(int64(v), 0), nil
case uint64:
return time.Unix(int64(v), 0), nil
case uint32:
return time.Unix(int64(v), 0), nil
default:
return time.Time{}, fmt.Errorf('unable to cast %#v of type %T to Time', i, i)
}
}

根据传入的类型执行不同的处理:

time.Time1970.01.01 00:00:00time.UnixUnixStringToDatetime.Parsetime.Timetime.Time

时长类型的转换代码如下:

// cast/caste.go
func ToDurationE(i interface{}) (d time.Duration, err error) {
i = indirect(i)

switch s := i.(type) {
case time.Duration:
return s, nil
case int, int64, int32, int16, int8, uint, uint64, uint32, uint16, uint8:
d = time.Duration(ToInt64(s))
return
case float32, float64:
d = time.Duration(ToFloat64(s))
return
case string:
if strings.ContainsAny(s, 'nsuµmh') {
d, err = time.ParseDuration(s)
} else {
d, err = time.ParseDuration(s + 'ns')
}
return
default:
err = fmt.Errorf('unable to cast %#v of type %T to Duration', i, i)
return
}
}

根据传入的类型进行不同的处理:

time.Durationtime.Durationnsnsuµmhtime.ParseDurationnstime.ParseDuration

示例:

转换为切片

实际上,这些函数的实现基本类似。使用类型断言判断类型。如果就是要返回的类型,直接返回。否则根据类型进行相应的转换。

ToIntSliceEToStringSliceEToBoolSliceE/ToDurationSliceEToIntSliceE
ToIntSliceE
func ToIntSliceE(i interface{}) ([]int, error) {
if i == nil {
return []int{}, fmt.Errorf('unable to cast %#v of type %T to []int', i, i)
}

switch v := i.(type) {
case []int:
return v, nil
}

kind := reflect.TypeOf(i).Kind()
switch kind {
case reflect.Slice, reflect.Array:
s := reflect.ValueOf(i)
a := make([]int, s.Len())
for j := 0; j < s.Len(); j++ {
val, err := ToIntE(s.Index(j).Interface())
if err != nil {
return []int{}, fmt.Errorf('unable to cast %#v of type %T to []int', i, i)
}
a[j] = val
}
return a, nil
default:
return []int{}, fmt.Errorf('unable to cast %#v of type %T to []int', i, i)
}
}

根据传入参数的类型:

nil[]int[]intint[]int[]int
ToStringSliceE

根据传入的参数类型:

[]interface{}string[]stringinterface{}stringstringstrings.Fields

示例:

package main

import (
'fmt'

'github.com/spf13/cast'
)

func main() {
sliceOfInt := []int{1, 3, 7}
arrayOfInt := [3]int{8, 12}
// ToIntSlice
fmt.Println(cast.ToIntSlice(sliceOfInt)) // [1 3 7]
fmt.Println(cast.ToIntSlice(arrayOfInt)) // [8 12 0]

sliceOfInterface := []interface{}{1, 2.0, 'darjun'}
sliceOfString := []string{'abc', 'dj', 'pipi'}
stringFields := ' abc def hij '
any := interface{}(37)
// ToStringSliceE
fmt.Println(cast.ToStringSlice(sliceOfInterface)) // [1 2 darjun]
fmt.Println(cast.ToStringSlice(sliceOfString)) // [abc dj pipi]
fmt.Println(cast.ToStringSlice(stringFields)) // [abc def hij]
fmt.Println(cast.ToStringSlice(any)) // [37]
}
map[string]Type
castmap[string]TypeType
ToStringMapStringEToStringMapStringEmap[string]string

根据传入的参数类型:

map[string]stringmap[string]interface{}stringmap[interface{}]stringstringmap[interface{}]interface{}stringstringcastmap[string]string

示例:

package main

import (
'fmt'

'github.com/spf13/cast'
)

func main() {
m1 := map[string]string {
'name': 'darjun',
'job': 'developer',
}

m2 := map[string]interface{} {
'name': 'jingwen',
'age': 18,
}

m3 := map[interface{}]string {
'name': 'pipi',
'job': 'designer',
}

m4 := map[interface{}]interface{} {
'name': 'did',
'age': 29,
}

jsonStr := `{'name':'bibi', 'job':'manager'}`

fmt.Println(cast.ToStringMapString(m1)) // map[job:developer name:darjun]
fmt.Println(cast.ToStringMapString(m2)) // map[age:18 name:jingwen]
fmt.Println(cast.ToStringMapString(m3)) // map[job:designer name:pipi]
fmt.Println(cast.ToStringMapString(m4)) // map[job:designer name:pipi]
fmt.Println(cast.ToStringMapString(jsonStr)) // map[job:manager name:bibi]
}

总结

cast