Golang 类型转换之cast库介绍

发布于:2024-10-13 ⋅ 阅读:(7) ⋅ 点赞:(0)

类型转换

在Golang开发中,类型转换是个不可避免的过程,我们经常需要把字符串转成int、bool类型,使用原生提供的strconv标准包比较繁琐,还需要处理err异常:

func ToInt(a string) int {
	b, _ := strconv.Atoi(a)
	return b
}

func ToBool(a string) bool {
	if a == "true" || a == "TRUE" {
		return true
	} else if a == "false" || a == "FALSE" {
		return false
	}
	return a == "1"
} 

Cast库

介绍

地址:github.com/spf13/cast

Cast库的作用就是封装了很多类型转换的方法,让引用这个库的开发者,能够以极简的方式把任意类型的值转换成指定类型。

package test

import (
	"encoding/json"
	"fmt"
	"github.com/spf13/cast"
	"go-learning/dao"
	"testing"
)

func TestCast(t *testing.T) {
	str := "123"
	fmt.Println(cast.ToString(str))  // 转成string
	fmt.Println(cast.ToStringE(str)) // 转成string,有error返回

	fmt.Println(cast.ToInt(str))  // 转成int,有error返回
	fmt.Println(cast.ToIntE(str)) // 转成int,有error返回

	fmt.Println(cast.ToInt64(str)) // 转成int64
	fmt.Println(cast.ToInt64(str)) // 转成int64,有error返回

	boolStr := "true"
	fmt.Println(cast.ToBool(boolStr))  // 转成bool
	fmt.Println(cast.ToBoolE(boolStr)) // 转成bool,有error返回
}

原理介绍

其实cast库的原理很简单,以cast.ToString()为例,就是通过断言获取到参数的类型,通过枚举所有支持的类型,结合strconv标准包、类型转换等方式实现任意类型的参数转换成string。

// ToStringE casts an interface to a string type.
func ToStringE(i interface{}) (string, error) {
	i = indirectToStringerOrError(i)

	switch s := i.(type) {
	case string:
		return s, nil
	case bool:
		return strconv.FormatBool(s), nil
	case float64:
		return strconv.FormatFloat(s, 'f', -1, 64), nil
	case float32:
		return strconv.FormatFloat(float64(s), 'f', -1, 32), nil
	case int:
		return strconv.Itoa(s), nil
	case int64:
		return strconv.FormatInt(s, 10), nil
	~~~~
	default:
		return "", fmt.Errorf("unable to cast %#v of type %T to string", i, i)
	}
}

缺点

返回默认值

cast库使用起来是比较简单的,不过也有一些缺点,比如对于不支持的类型,会返回一个默认值,如果使用的是cast.ToString()方法,就无法感知到这个默认值并不是你期望返回的,从而导致程序运行的结果不符合预期。

type MyType int

func TestErrCast(t *testing.T) {
	var num MyType = 1
	fmt.Println(num)                  // 1
	fmt.Println(cast.ToString(num))   // ""
	fmt.Println(cast.ToInt(num))      // 0
	fmt.Println(cast.ToInt(int(num))) // 1
}
性能问题

在cast库的原理介绍中,通过ToString()方法介绍了cast库是基于断言、类型转换等方法实现的,在性能上并没有优势,尤其是泛型出现后;

但cast库的优势也很明显,在不追求极致性能的场景下,开发者可以使用简洁的方式实现类型转换,从而让代码看起来更简洁。