共计 2249 个字符,预计需要花费 6 分钟才能阅读完成。
引言
还在为 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 day001
import (
"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
- 局部字符转换可能不如意,比方 cast.ToInt64E(“8.99”) 得出的是 0,而不是 8or9,起因能够尝试读一下源码,也不简单。
- 办法后 +E,能够多返回一个参数 error,比方 ToIntE。
源码解读
cast 库的源码比较简单,相熟语法的应该都能看明确。
咱们以 ToFloat64 为 🌰,解析我就放正文了
// 间接调用 ToFloat64E
func 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()}
正文完