文章目录
Golang类型转换工具库cast
简介
cast
可以在 Go 中轻松安全地从一种类型转换为另一种类型,cast
提供了简单的函数来轻松地将数字转换为字符串,将接口转换为布尔值等。当需要显示类型转换时,cast
会智能地执行转换操作。
快速入门
安装
go get github.com/spf13/cast
使用
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
实现了多种常见类型之间的相互转换,返回最符合直觉的结果。例如:
nil
转为string
的结果为""
,而不是"nil"
;true
转为string
的结果为"true"
,而true
转为int
的结果为1
;interface{}
转为其他类型,要看它里面存储的值类型。
这些类型包括所有的基本类型(整形、浮点型、布尔值和字符串)、空接口、nil
,时间(time.Time
)、时长(time.Duration
)以及它们的切片类型,还有map[string]Type
(其中Type
为前面提到的类型):
byte bool float32 float64 string
int8 int16 int32 int64 int
uint8 uint16 uint32 uint64 uint
interface{} time.Time time.Duration nil
高级转换
cast
提供了两组函数:
ToType
(其中Type
可以为任何支持的类型),将参数转换为Type
类型。如果无法转换,返回Type
类型的零值或nil
;ToTypeE
以 E 结尾,返回转换后的值和一个error
。这组函数可以区分参数中实际存储了零值,还是转换失败了。
实现上大部分代码都类似,ToType
在内部调用ToTypeE
函数,返回结果并忽略错误。ToType
函数的实现在文件cast.go
中,而ToTypeE
函数的实现在文件caste.go
中。
部分源码如下:
// ToBoolE casts an interface to a bool type.
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
}
ToTypeE
函数都接受任意类型的参数(interface{}
),然后使用类型断言根据具体的类型来执行不同的转换。如果无法转换,返回错误。
// ToBoolE casts an interface to a bool type.
func ToBoolE(i interface{
}) (bool, error) {
i = indirect(i)
switch b := i.(type) {
case bool:
return b, nil
case nil:
return false, nil
case int:
if i.(int) != 0 {
return true, nil
}
return false, nil
case string:
return strconv.ParseBool(i.(string))
case json.Number:
v, err := ToInt64E(b)
if err == nil {
return v != 0, nil
}
return false, fmt.Errorf("unable to cast %#v of type %T to bool", i, i)
default:
return false, fmt.Errorf("unable to cast %#v of type %T to bool", i, i)
}
}
首先调用indirect
函数将参数中可能的指针去掉。如果类型本身不是指针,那么直接返回。否则返回指针指向的值。循环直到返回一个非指针的值:
// From html/template/content.go
// Copyright 2011 The Go Authors. All rights reserved.
// indirect