golang快速直观的Go类型转换插件库conv的使用

Golang快速直观的Go类型转换插件库conv的使用

简介

conv是一个提供快速直观Go类型转换的库。它使用反射来确保健壮性,但对于常见转换(如字符串到任何类型)会绕过反射。所有函数都是并发安全的。

安装

go get -u github.com/cstockton/go-conv

基本用法

基本类型转换

// 基本类型转换
if got, err := conv.Bool(`TRUE`); err == nil {
    fmt.Printf("conv.Bool(`TRUE`)\n  -> %v\n", got)
}
if got, err := conv.Duration(`1m2s`); err == nil {
    fmt.Printf("conv.Duration(`1m2s`)\n  -> %v\n", got)
}
var date time.Time
err := conv.Infer(&date, `Sat Mar 7 11:06:39 PST 2015`)
fmt.Printf("conv.Infer(&date, `Sat Mar 7 11:06:39 PST 2015`)\n  -> %v\n", date)

输出:

conv.Bool(`TRUE`)
  -> true
conv.Duration(`1m2s`)
  -> 1m2s
conv.Infer(&date, `Sat Mar 7 11:06:39 PST 2015`)
  -> 2015-03-07 11:06:39 +0000 PST

主要功能

Bool转换

// Bool转换示例
fmt.Println(conv.Bool("T"))      // true
fmt.Println(conv.Bool("False")) // false
fmt.Println(conv.Bool(int64(123))) // true
fmt.Println(conv.Bool(int64(0)))   // false

Duration转换

// Duration转换示例
fmt.Println(conv.Duration("1h1m100ms"))     // 1h1m0.1s
fmt.Println(conv.Duration("3660100000000")) // 1h1m0.1s
fmt.Println(conv.Duration(3660100000000))   // 1h1m0.1s

Float64转换

// Float64转换示例
fmt.Println(conv.Float64(float64(123.456))) // 123.456
fmt.Println(conv.Float64("-123.456"))       // -123.456

Infer推断转换

// Infer推断转换示例
var into int
if err := conv.Infer(into, `42`); err != nil {
    fmt.Println(err) // 需要指针
}
if err := conv.Infer(&into, `42`); err == nil {
    fmt.Println(into) // 42
}

Int转换

// Int转换示例
fmt.Println(conv.Int("-123.456")) // -123
fmt.Println(conv.Uint("-123.456")) // 0

String转换

// String转换示例
fmt.Println(conv.String("Foo")) // Foo
fmt.Println(conv.String([]byte("Foo"))) // Foo

Time转换

// Time转换示例
fmt.Println(conv.Time(time.Date(2006, 1, 2, 15, 4, 5, 0, time.UTC)))
fmt.Println(conv.Time("Mon, 02 Jan 2006 15:04:05"))

Uint转换

// Uint转换示例
fmt.Println(conv.Uint("123.456")) // 123
fmt.Println(conv.Uint8(uint64(math.MaxUint64))) // 255

数值转换规则

数值转换遵循以下规则:

  • 相同类型的数值直接返回
  • 溢出时返回目标类型的最大值
  • 下溢时返回目标类型的最小值(无符号整数返回0)
fmt.Println(conv.Int("-123.456")) // -123
fmt.Println(conv.Uint("-123.456")) // 0

错误处理

所有转换函数在无法找到合理的转换路径时,会返回目标类型的零值和一个错误。

fmt.Println(conv.Int("Foo")) // 0 cannot convert "Foo" (type string) to int

注意事项

  • 该库设计为不会panic(除非运行时环境不稳定)
  • 零值map和slice类型会被视为false
  • 指针会被自动解引用
fmt.Println(conv.Bool(nil)) // false
fmt.Println(conv.Bool([][]int{})) // false

这个库提供了简单直观的类型转换方式,特别适合需要处理多种输入类型的场景。


更多关于golang快速直观的Go类型转换插件库conv的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang快速直观的Go类型转换插件库conv的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Go类型转换库conv的使用指南

conv是一个简单高效的Go语言类型转换库,它提供了直观的API来处理各种常见的数据类型转换。下面我将详细介绍conv库的主要功能和用法。

安装conv库

go get github.com/cstockton/go-conv

基本类型转换

字符串与其他类型的转换

package main

import (
	"fmt"
	"github.com/cstockton/go-conv"
)

func main() {
	// 字符串转整数
	i, err := conv.Int("123")
	fmt.Println(i, err) // 123 <nil>

	// 字符串转浮点数
	f, err := conv.Float64("3.14")
	fmt.Println(f, err) // 3.14 <nil>

	// 字符串转布尔值
	b, err := conv.Bool("true")
	fmt.Println(b, err) // true <nil>

	// 其他类型转字符串
	s := conv.String(123)
	fmt.Println(s) // "123"
}

数值类型之间的转换

// 整数之间转换
i32 := int32(123)
i64, err := conv.Int64(i32)
fmt.Println(i64, err) // 123 <nil>

// 浮点数转整数(会截断小数部分)
f := 3.99
i, err := conv.Int(f)
fmt.Println(i, err) // 3 <nil>

// 整数转浮点数
i := 42
f, err := conv.Float64(i)
fmt.Println(f, err) // 42 <nil>

时间类型转换

conv库对时间类型提供了良好的支持:

// 字符串转时间
t, err := conv.Time("2023-01-01 12:00:00")
fmt.Println(t, err) // 2023-01-01 12:00:00 +0000 UTC <nil>

// 时间戳转时间
ts := int64(1672531200) // Unix时间戳
t, err := conv.Time(ts)
fmt.Println(t, err) // 2023-01-01 00:00:00 +0000 UTC <nil>

// 时间转字符串
now := time.Now()
s := conv.String(now)
fmt.Println(s) // "2023-01-01 12:00:00 +0000 UTC"

切片和数组转换

// 字符串切片转整数切片
strSlice := []string{"1", "2", "3"}
intSlice, err := conv.IntSlice(strSlice)
fmt.Println(intSlice, err) // [1 2 3] <nil>

// 混合类型切片转字符串切片
mixedSlice := []interface{}{1, "2", 3.0}
strSlice, err := conv.StringSlice(mixedSlice)
fmt.Println(strSlice, err) // ["1" "2" "3"] <nil>

结构体和Map转换

type Person struct {
	Name string
	Age  int
}

// 结构体转Map
p := Person{Name: "Alice", Age: 30}
m, err := conv.Map(p)
fmt.Println(m, err) // map[Age:30 Name:Alice] <nil>

// Map转结构体
data := map[string]interface{}{"Name": "Bob", "Age": 25}
var p2 Person
err := conv.MapStruct(data, &p2)
fmt.Println(p2, err) // {Bob 25} <nil>

错误处理

conv库提供了多种错误处理方式:

// 直接转换,出错会panic
i := conv.MustInt("123")
fmt.Println(i) // 123

// 安全转换,返回错误
i, err := conv.Int("abc")
if err != nil {
	fmt.Println("转换失败:", err)
}

// 默认值转换
i := conv.DefaultInt("abc", 0)
fmt.Println(i) // 0 (因为转换失败使用默认值)

性能优化技巧

  1. 对于频繁转换的场景,可以重用转换器实例:
c := conv.NewConverter()
i, err := c.Int("123")
  1. 对于已知安全的转换,使用Must系列函数避免错误检查开销:
i := conv.MustInt("123")
  1. 批量转换时使用Slice系列函数比循环转换更高效:
// 比循环调用conv.Int更高效
intSlice := conv.MustIntSlice([]string{"1", "2", "3"})

总结

conv库提供了以下主要优势:

  1. 简单直观的API设计
  2. 全面的类型转换支持
  3. 良好的错误处理机制
  4. 合理的性能表现

适用于需要频繁进行类型转换的场景,特别是处理来自外部的不确定类型数据时,如JSON解析、数据库查询结果处理等。

注意:虽然conv库很方便,但在性能关键的代码路径中,还是应该使用标准库的类型转换方法,因为它们通常有更好的性能。

回到顶部