cast - 类型转换库
cast 是一个简单易用的类型转换函数库,提供字符串到各种 Go 基本类型的转换功能。最低支持 Go 1.21.0 版本。
安装
go get -u go-slim.dev/cast快速开始
package mainimport ( "fmt" "go-slim.dev/cast")func main() { // 字符串转整数 num, _ := cast.Int("42") fmt.Println(num) // 42 // 字符串转布尔值 flag, _ := cast.Bool("true") fmt.Println(flag) // true // 字符串转时间 t, _ := cast.Time("2023-12-25T10:30:45Z") fmt.Println(t)}Bool - 布尔值转换
函数签名
func Bool(s string) (bool, error)说明
将字符串解析成 bool 值,内部使用标准库 strconv.ParseBool 实现。
支持的值:
true: “1”, “t”, “T”, “true”, “TRUE”, “True”false: “0”, “f”, “F”, “false”, “FALSE”, “False”
示例
// 返回 truecast.Bool("true")cast.Bool("TRUE")cast.Bool("1")cast.Bool("t")// 返回 falsecast.Bool("false")cast.Bool("FALSE")cast.Bool("0")cast.Bool("f")// 返回错误cast.Bool("yes") // 不支持的值cast.Bool("no") // 不支持的值Uint 系列 - 无符号整数转换
函数签名
func Uint(s string) (uint, error)func Uint8(s string) (uint8, error)func Uint16(s string) (uint16, error)func Uint32(s string) (uint32, error)func Uint64(s string) (uint64, error)说明
将字符串解析成对应类型的无符号整数值,内部使用标准库 strconv.ParseUint 实现。
支持的格式:
- 十进制:
"123" - 十六进制:
"0x7B"(前缀 0x) - 八进制:
"0173"(前缀 0) - 二进制:
"0b1111011"(前缀 0b)
示例
// 十进制num, _ := cast.Uint("123") // 123num8, _ := cast.Uint8("255") // 255// 十六进制num, _ := cast.Uint("0xFF") // 255// 八进制num, _ := cast.Uint("0777") // 511// 二进制num, _ := cast.Uint("0b1010") // 10// 超出范围会返回错误_, err := cast.Uint8("256") // 错误:超出 uint8 范围Int 系列 - 有符号整数转换
函数签名
func Int(s string) (int, error)func Int8(s string) (int8, error)func Int16(s string) (int16, error)func Int32(s string) (int32, error)func Int64(s string) (int64, error)说明
将字符串解析成对应类型的有符号整数值,内部使用标准库 strconv.ParseInt 实现。
支持的格式:
- 十进制:
"123","-123" - 十六进制:
"0x7B","-0x7B" - 八进制:
"0173","-0173" - 二进制:
"0b1111011","-0b1111011"
示例
// 正数num, _ := cast.Int("42") // 42// 负数num, _ := cast.Int("-42") // -42// 十六进制num, _ := cast.Int32("0xFF") // 255num, _ := cast.Int32("-0xFF") // -255// 超出范围会返回错误_, err := cast.Int8("128") // 错误:超出 int8 范围 (-128 到 127)Float 系列 - 浮点数转换
函数签名
func Float32(s string) (float32, error)func Float64(s string) (float64, error)说明
将字符串解析成对应类型的浮点数值,内部使用标准库 strconv.ParseFloat 实现。
示例
// 普通浮点数num, _ := cast.Float64("3.14") // 3.14num, _ := cast.Float64("-2.5") // -2.5// 科学计数法num, _ := cast.Float64("1.23e-4") // 0.000123num, _ := cast.Float64("1E6") // 1000000// 特殊值num, _ := cast.Float64("Inf") // +Infnum, _ := cast.Float64("-Inf") // -Infnum, _ := cast.Float64("NaN") // NaNDecimal - 高精度十进制转换
函数签名
func Decimal(s string) (decimal.Decimal, error)说明
将字符串解析成高精度的十进制数值,使用 github.com/shopspring/decimal 包实现。适用于需要精确计算的场景,如金融计算。
示例
import "github.com/shopspring/decimal"// 高精度计算d1, _ := cast.Decimal("0.1")d2, _ := cast.Decimal("0.2")sum := d1.Add(d2) // 精确的 0.3// 避免浮点数精度问题// float64: 0.1 + 0.2 = 0.30000000000000004// decimal: 0.1 + 0.2 = 0.3Time - 时间转换
函数签名
func Time(s string) (time.Time, error)说明
将字符串解析成 time.Time 值。支持多种常见的时间格式,包括 RFC 标准格式、常见日期格式和 Unix 时间戳。
支持的格式:
- RFC3339:
"2006-01-02T15:04:05Z07:00" - 日期时间:
"2006-01-02 15:04:05" - 仅日期:
"2006-01-02" - Unix 时间戳:
"1703505045"(秒) - 带纳秒:
"2006-01-02 15:04:05.999999999" - 其他 RFC 格式: RFC1123, RFC822, 等
示例
// RFC3339 格式t, _ := cast.Time("2023-12-25T10:30:45Z")// 常见日期格式t, _ := cast.Time("2023-12-25")t, _ := cast.Time("2023-12-25 10:30:45")t, _ := cast.Time("2023/12/25")// Unix 时间戳t, _ := cast.Time("1703505045") // 2023-12-25 10:30:45 UTC// 美国日期格式t, _ := cast.Time("12/25/2023")t, _ := cast.Time("Dec 25, 2023")// RFC 格式t, _ := cast.Time("Mon, 02 Jan 2006 15:04:05 MST")Duration - 时间间隔转换
函数签名
func Duration(s string) (time.Duration, error)说明
将字符串解析成 time.Duration 值。支持多种输入格式。
支持的格式:
- Go 标准格式:
"1h30m45s","500ms","2h" - 整数: 视为纳秒
- 浮点数: 视为秒
示例
// Go 标准格式d, _ := cast.Duration("1h30m45s") // 1 小时 30 分 45 秒d, _ := cast.Duration("500ms") // 500 毫秒d, _ := cast.Duration("2h") // 2 小时// 整数(纳秒)d, _ := cast.Duration("1000000000") // 1 秒(10 亿纳秒)// 浮点数(秒)d, _ := cast.Duration("1.5") // 1.5 秒d, _ := cast.Duration("0.001") // 1 毫秒FromString - 通用类型转换
函数签名
func FromString(s string, targetType string) (any, error)说明
这是对所有类型转换函数的封装,根据类型名称字符串动态选择转换函数。
支持的类型名称:
- 整数:
"int","int8","int16","int32","int64" - 无符号整数:
"uint","uint8","uint16","uint32","uint64" - 浮点数:
"float32","float64" - 布尔值:
"bool" - 字符串:
"string" - 时间:
"time.Time","time.Duration"
示例
// 整数转换v, _ := cast.FromString("42", "int") // int(42)v, _ := cast.FromString("255", "uint8") // uint8(255)// 浮点数转换v, _ := cast.FromString("3.14", "float64") // float64(3.14)// 布尔值转换v, _ := cast.FromString("true", "bool") // bool(true)// 字符串转换v, _ := cast.FromString("hello", "string") // string("hello")// 时间转换v, _ := cast.FromString("2023-12-25", "time.Time")v, _ := cast.FromString("1h30m", "time.Duration")// 不支持的类型会返回错误_, err := cast.FromString("42", "complex64") // 错误:不支持的类型FromType - 基于反射的转换
函数签名
func FromType(s string, targetType reflect.Type) (any, error)说明
该函数表示将字符串 s 转换成目标类型 targetType,并返回该类型对应的值。支持基本类型和切片类型。
切片类型支持:
- 对于切片类型(如
[]int,[]string),输入字符串会按逗号分割 - 每个元素会被 trim 并转换为元素类型
- 示例:
"1,2,3"→[]int{1, 2, 3}
示例
import "reflect"// 基本类型t := reflect.TypeOf(0)v, _ := cast.FromType("42", t) // int(42)// 切片类型t := reflect.TypeOf([]int(nil))v, _ := cast.FromType("1,2,3", t) // []int{1, 2, 3}t := reflect.TypeOf([]string(nil))v, _ := cast.FromType("a,b,c", t) // []string{"a", "b", "c"}// 带空格的切片v, _ := cast.FromType("1, 2, 3", t) // 自动 trim 空格// 结果: []int{1, 2, 3}使用场景
1. 配置文件解析
import "go-slim.dev/cast"// 从环境变量或配置文件读取port, _ := cast.Int(os.Getenv("PORT"))debug, _ := cast.Bool(os.Getenv("DEBUG"))timeout, _ := cast.Duration(os.Getenv("TIMEOUT"))2. HTTP 参数处理
func handler(c slim.Context) error { // 查询参数转换 page, err := cast.Int(c.QueryParam("page")) if err != nil { return c.String(400, "Invalid page number") } limit, _ := cast.Int(c.QueryParam("limit")) // ... 使用 page 和 limit}3. 数据库值转换
// 从数据库读取的字符串值var priceStr stringdb.QueryRow("SELECT price FROM products WHERE id = ?", id).Scan(&priceStr)// 转换为高精度 Decimalprice, _ := cast.Decimal(priceStr)4. 命令行参数解析
import "flag"var ( portStr = flag.String("port", "8080", "server port") debugStr = flag.String("debug", "false", "debug mode"))func main() { flag.Parse() port, _ := cast.Int(*portStr) debug, _ := cast.Bool(*debugStr) // ... 使用 port 和 debug}错误处理
所有转换函数都返回 error,应该适当处理:
// 基本错误处理num, err := cast.Int("abc")if err != nil { log.Printf("转换失败: %v", err) return}// 使用默认值num, err := cast.Int(input)if err != nil { num = 0 // 使用默认值}// 链式转换value := "42"if num, err := cast.Int(value); err == nil { // 使用 num} else { // 处理错误}性能说明
- 所有函数都是对标准库的薄包装,性能开销极小
- 没有使用反射(除了
FromType函数) - 适用于高性能场景
Decimal类型会有额外的性能开销,但提供了精确的十进制运算
注意事项
-
类型范围检查:超出目标类型范围的值会返回错误
_, err := cast.Uint8("256") // 错误:超出范围 (0-255) -
空字符串:大多数函数对空字符串会返回错误
_, err := cast.Int("") // 错误 -
字符串类型:
FromString("...", "string")总是成功v, _ := cast.FromString("anything", "string") // 总是返回原字符串 -
时间格式:
Time()会尝试多种格式,选择第一个匹配的t, _ := cast.Time("2023-12-25") // 成功t, _ := cast.Time("invalid") // 错误 -
浮点数精度:金融计算使用
Decimal而非Float// 不推荐f, _ := cast.Float64("0.1")// 推荐(金融场景)d, _ := cast.Decimal("0.1")