Go 语言类型转换的陷阱

开发 前端
本文我们介绍 Go 语言类型转换的两个库,分别是标准库 strconv​ 和三方库 cast​,其中 cast 更方便、更安全,但是也有陷阱,我们需要特别注意,避免在项目开发中掉进陷阱。

01 介绍

Go 语言作为强类型语言,在使用 Golang 开发项目时,经常会遇到类型转换的场景,整型之间可以直接转换,字节切片和字符串之间也可以直接转换。

但是,如果整型和字符串之间做类型转换,则需要使用 strconv 标准库提供的函数。

02 标准库 strconv 类型转换

Go 语言标准库 strconv[1] 提供了一些类型转换的函数,比如在项目开发中使用比较多的整型和字符串之间的类型转换。

func main() {
 salary := 5000
 salaryStr := strconv.Itoa(salary)
 fmt.Printf("%T salary=%d\n", salary, salary)
 fmt.Printf("%T salaryStr=%s\n", salaryStr, salaryStr)

 age := "23"
 ageInt, err := strconv.Atoi(age)
 fmt.Printf("%T age=%s\n", age, age)
 fmt.Printf("%T ageInt=%d err=%v\n", ageInt, ageInt, err)
}

输出结果:

int salary=5000
string salaryStr=5000
string age=23
int ageInt=23 err=<nil>

阅读上面这段代码,我们使用标准库 strconv 将整型变量 salary 转换为字符串类型变量 salaryStr;将字符串类型变量 age 转换为整型变量 ageInt。

但是,读者朋友们有没有发现一个问题,我们使用标准库 strconv 提供的函数 Atoi 将字符串类型变量转换为整型变量,得到的是 int 类型,如果我们需要得到一个 int8 类型的变量,我们需要继续做类型转换,例如:

age := "23"
ageInt, err := strconv.Atoi(age)
ageInt8 := int8(ageInt)

也就是说,如果我们需要将一个字符串类型的变量转换为一个非 int 类型的整型变量,需要做二次转换,在实际项目开发中,使用起来稍微繁琐一些。

此外,使用标准库 strconv 做类型转换,除了在一些场景中稍微繁琐之外,还有另外一个问题,我们先阅读以下一段代码。

func main() {
  phoneNumber := "138001380001380013800013800138000"
 phoneNumberInt, err := strconv.Atoi(phoneNumber)
 fmt.Printf("%T phoneNumber=%s\n", phoneNumber, phoneNumber)
 fmt.Printf("%T phoneNumberInt=%d err=%v\n", phoneNumberInt, phoneNumberInt, err)
}

输出结果:

string phoneNumber=138001380001380013800013800138000
int phoneNumberInt=9223372036854775807 err=strconv.Atoi: parsing "138001380001380013800013800138000": value out of range

阅读上面这段代码输出的错误信息 value out of range,也就是说如果我们需要转换的值超出返回,Go 语言标准库 strconv 提供的函数 Atoi 会返回错误。

所以,在使用函数 Atoi 时,我们要做好参数验证和错误处理。

有没有使用更简单的类型转换库,接下来,我们来看一下流行的三方库 cast。

03 三方库 cast 类型转换

Go 类型转换的三方库 cast 是一个使用比较多的库,我们使用 cast[2] 来处理 Part02 的类型转换需求,代码如下:

func main() {
  age2 := "23"
 age2Int8 := cast.ToInt8(age2)
 fmt.Printf("%T age2=%s\n", age2, age2)
 fmt.Printf("%T age2Int8=%d\n", age2Int8, age2Int8)

 phoneNumber2 := "138001380001380013800013800138000"
 phoneNumber2Int := cast.ToInt(phoneNumber2)
 fmt.Printf("%T phoneNumber2=%s\n", phoneNumber2, phoneNumber2)
 fmt.Printf("%T phoneNumber2Int=%d\n", phoneNumber2Int, phoneNumber2Int)
}

输出结果:

string age2=23
int8 age2Int8=23
string phoneNumber2=138001380001380013800013800138000
int phoneNumber2Int=0

阅读上面这段代码,我们可以发现,使用 cast 可以直接将字符串类型的变量转换为我们需要的整型变量,使用起来不再感到繁琐。

同时,需要注意的是,如果转换失败,将返回类型零值,字符串类型变量 phoneNumber2 在使用 cast 转换为 int 类型的变量时,返回的结果就是 int 的类型零值。

使用 cast 比使用 strconv 更简单,而且不需要处理错误。但是,cast 还有一个陷阱,我们需要特别注意一下,我们先阅读以下一段代码:

func main() {
  month := "07"
 monthInt8 := cast.ToInt8(month)
 fmt.Printf("%T month=%s\n", month, month)
 fmt.Printf("%T monthInt8=%d\n", monthInt8, monthInt8)

 month2 := "08"
 month2Int8 := cast.ToInt8(month2)
 fmt.Printf("%T month2=%s\n", month2, month2)
 fmt.Printf("%T month2Int8=%d\n", month2Int8, month2Int8)
}

输出结果:

string month=07
int8 monthInt8=7
string month2=08
int8 month2Int8=0

阅读上面这段代码的输出结果,我们可以发现使用 cast 将字符串类型 month 和 month2 转换为整型时,字符串是以 "0" 开头的月份,"07" 转换后得到整型 7,而 "08" 转换后得到整型 0。

我们再使用 strconv 转换 "08",代码如下:

func main() {
  month2 := "08"
 month2Int8 := cast.ToInt8(month2)
 fmt.Printf("%T month2=%s\n", month2, month2)
 fmt.Printf("%T month2Int8=%d\n", month2Int8, month2Int8)

 month2Int2, err := strconv.Atoi(month2)
 fmt.Printf("%T month2Int2=%d err=%v\n", month2Int2, month2Int2, err)
}

输出结果:

int8 month2Int8=0
int month2Int2=8 err=<nil>

读者朋友们从输出结果可以看到,"08" 使用 strconv 转换后得到整型 8,所以我们在转换以一个或多个 "0" 开头的字符串为整型时,字符串 "0" 后面的数值大于 7 将不能使用 cast 转换,最好就是在转换以一个或多个 "0" 开头的字符串为整型时,比如 "08"、"009"、"00010" 等,使用 strconv 转换,而不要使用 cast 转换。

04 总结

本文我们介绍 Go 语言类型转换的两个库,分别是标准库 strconv 和三方库 cast,其中 cast 更方便、更安全,但是也有陷阱,我们需要特别注意,避免在项目开发中掉进陷阱。

责任编辑:武晓燕 来源: Golang语言开发栈
相关推荐

2021-07-08 23:53:44

Go语言拷贝

2023-07-16 23:43:05

Go语言模式

2023-07-03 00:44:26

Go语言MySQL

2024-04-26 00:01:00

Go语言类型

2024-01-07 23:11:16

defer​Go语言

2024-05-10 08:04:44

开发者Go语言

2023-10-29 16:18:26

Go接口

2021-10-03 22:18:14

Go语言整数

2012-12-11 09:16:07

Go

2021-03-10 10:00:31

Go语言strconv包类型转换工具

2021-11-14 23:05:28

GoCast语言

2012-10-08 09:25:59

GoGo语言开发语言

2010-07-14 17:03:52

编程语言

2023-12-04 18:31:59

C语言函数

2024-06-12 08:54:49

Go切片参数

2018-03-12 22:13:46

GO语言编程软件

2024-06-11 08:30:31

2020-08-20 11:50:31

语言类型转换代码

2021-11-23 23:31:43

C语言数据类型系统

2011-07-14 10:23:33

C语言
点赞
收藏

51CTO技术栈公众号