Slim

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")            // NaN

Decimal - 高精度十进制转换

函数签名

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.3

Time - 时间转换

函数签名

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 类型会有额外的性能开销,但提供了精确的十进制运算

注意事项

  1. 类型范围检查:超出目标类型范围的值会返回错误

    _, err := cast.Uint8("256")  // 错误:超出范围 (0-255)
  2. 空字符串:大多数函数对空字符串会返回错误

    _, err := cast.Int("")       // 错误
  3. 字符串类型FromString("...", "string") 总是成功

    v, _ := cast.FromString("anything", "string")  // 总是返回原字符串
  4. 时间格式Time() 会尝试多种格式,选择第一个匹配的

    t, _ := cast.Time("2023-12-25")              // 成功t, _ := cast.Time("invalid")                 // 错误
  5. 浮点数精度:金融计算使用 Decimal 而非 Float

    // 不推荐f, _ := cast.Float64("0.1")// 推荐(金融场景)d, _ := cast.Decimal("0.1")

相关链接

切换 选择 esc 关闭搜索