引言

还在为golang麻烦的类型转换懊恼吗?

无妨试下 spf13 大神的 cast 吧。

我的项目地址

我的项目地址: https://github.com/spf13/cast[star:2.5k]

应用场景

  • 类型转换

装置

go get github.com/spf13/cast

罕用办法

  • ToString 转换为字符串
  • ToInt 转换为 int
  • ToBool 转换为布尔值
  • ToTime 转换为 time.Time
  • ToStringE 转换为字符串,返回字符串和error

例子

package day001import (    "testing"    "github.com/spf13/cast")func TestCast(t *testing.T) {    t.Log("cast.ToString")    t.Log(cast.ToString("https://oscome.cn"))    t.Log(cast.ToString(8.88))    t.Log(cast.ToString([]byte("https://oscome.cn")))    var abc interface{} = "https://oscome.cn"    t.Log(cast.ToString(abc))    t.Log("cast.ToInt")    t.Log(cast.ToInt("8"))    // 前面+E 能够多返回一个 error 参数    t.Log(cast.ToInt64E("8.99"))    t.Log("cast.ToInt")    t.Log(cast.ToBool("1"))    t.Log(cast.ToBool("8.99"))}

成果如下:

cast 能做的不止如此,除了常见类型,还提供了工夫类办法 ToTime、ToDuration,甚至还有切片类转换 ToStringSlice、ToStringMap,弱小又好用。本人入手试一试吧!

func TestCastMore(t *testing.T) {    t.Log("cast.ToTime")    t.Log(cast.ToTime("2022-01-02 01:01:01 +0000 UTC"))    t.Log("cast.ToDuration")    t.Log(cast.ToDuration(1e9))    t.Log("cast.ToStringSlice")    t.Log(cast.ToStringSlice([]int{1, 3}))}

实例代码

https://github.com/oscome/god...

tips

  1. 局部字符转换可能不如意,比方 cast.ToInt64E("8.99") 得出的是0,而不是8or9,起因能够尝试读一下源码,也不简单。
  2. 办法后+E,能够多返回一个参数 error,比方 ToIntE。

源码解读

cast 库的源码比较简单,相熟语法的应该都能看明确。

咱们以 ToFloat64 为 ,解析我就放正文了

// 间接调用 ToFloat64Efunc ToFloat64(i interface{}) float64 {    v, _ := ToFloat64E(i)    return v}func ToFloat64E(i interface{}) (float64, error) {    i = indirect(i)    // toInt 里类型申明,case 判断,没什么好说的    intv, ok := toInt(i)    if ok {        return float64(intv), nil    }    // 类型判断    switch s := i.(type) {    case float64:        return s, nil    case float32:        return float64(s), nil    ...    case string:        // 个别应用的 string 到 float64 的类型转换办法        v, err := strconv.ParseFloat(s, 64)        if err == nil {            return v, nil        }        return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)    case json.Number:        v, err := s.Float64()        if err == nil {            return v, nil        }        return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)    case bool:        if s {            return 1, nil        }        return 0, nil    case nil:        return 0, nil    default:        return 0, fmt.Errorf("unable to cast %#v of type %T to float64", i, i)    }}func indirect(a interface{}) interface{} {    if a == nil {        return nil    }    // 通过反射获取类型信息,具体类型可见 https://golang.google.cn/pkg/reflect/#Kind    if t := reflect.TypeOf(a); t.Kind() != reflect.Ptr {        // 不是指针类型,间接返回        return a    }    // ValueOf 返回一个新值,初始化为存储在接口 a 中的具体值。 ValueOf(nil) 返回零值。    v := reflect.ValueOf(a)    // 这里能够简略了解成解一次指针的援用    // Elem 返回接口 v 蕴含的值或指针 v 指向的值。如果 v 的 Kind 不是接口或指针,会报 panic 。如果 v 为零,则返回零值。    for v.Kind() == reflect.Ptr && !v.IsNil() {        v = v.Elem()    }    // 返回 v 以后值作为的接口    return v.Interface()}