一文带你了解Golang中类型转换库cast的使用
来源:脚本之家
时间:2023-02-25 09:31:55 190浏览 收藏
Golang小白一枚,正在不断学习积累知识,现将学习到的知识记录一下,也是将我的所得分享给大家!而今天这篇文章《一文带你了解Golang中类型转换库cast的使用》带大家来了解一下一文带你了解Golang中类型转换库cast的使用,希望对大家的知识积累有所帮助,从而弥补自己的不足,助力实战开发!
0 前言
你是否在使用 Go 的过程中因为类型转换的繁琐而苦恼过?
你是否觉得 Go 语言中的类型断言可能会 panic 而对自己写的代码有那么一点点不放心?
如果你有过如上体验,并且想要找到一个合适的解决方案的话,那么本文推荐的一个用于类型转换的第三方库 cast 绝对是一个值得尝试的选择。
1 cast
cast 是一个极为简洁的第三方库,github 地址:https://github.com/spf13/cast。
项目主页里的头两句介绍就是:
Easy and safe casting from one type to another in Go
Don’t Panic! ... Cast
可见,cast 的主要功能就是类型转换,且没有 panic。
多说一句,Don't panic 在英语中本身就是一个常用语,表示不要慌张、不要害怕,所以,在这里其实是一个有意思的双关。
2 上手
2.1 安装引入
这里只讲 go mod 的引入方式。
在 go.mod 文件中 require github.com/spf13/cast v1.5.0(目前最新版为 1.5.0),接着用 mod 进行 download、tidy 等操作,再在代码中 import "github.com/spf13/cast" 即可使用 cast 关键字使用 cast 的功能了。
2.2 使用
2.2.1 常规用法
我们直接通过几个简单的例子来体验一下 cast:
var target interface{} = "123"
str := "hello, world!"
fmt.Println(cast.ToString(target))
fmt.Println(cast.ToInt(target))
fmt.Println(cast.ToInt(str))
// 输出:
123
123
0我们创建了一个 interface{} 类型的变量 target,传统方式下如果要将一个 interface{} 转化为 string,需要使用类型断言:
var target interface{} = "123"
str := target.(string)
// or
str, ok := target.(string)类型断言的缺点很明显,如果不接收第二个返回值,会有 panic 风险;如果接收第二个参数,则略显繁琐。
到了第二个 ToInt,cast 的优势就更明显了,传统方式下,一个 interface{} 类型的 "123" 如果要转换成 int,必须先类型断言为 string,再使用 strconv 转换成 int,代码就不写了,想象一下就知道有多麻烦,而 cast 可以将这个过程一步到位。
接着是第三个输出 cast.ToInt(str),这里的 str 是一个 string 类型的 "hello, world!",它显然不能被转换成 int,于是 cast 将其设置为 int 的零值 0。
其实 cast 的所有类型转换都会将无法转换的结果转为零值,而不是 panic,这也就是 cast 官方承诺的 Don't panic。
2.2.2 带 error 的用法
看到这里,有朋友可能要问了:如果我的逻辑必须判断目标是否转换成功了呢?如果我的转换结果就有可能是 0 呢?我怎么知道这个 0 是转换失败的零值,还是目标原始的真实值?
cast 的作者自然也想到了这一点,于是,cast 的所有类型转换函数都有一个对应的 with error 版:
str := "hello" strNum := "123" num, e := cast.ToIntE(str) fmt.Println(num) fmt.Println(e) num, e = cast.ToIntE(strNum ) fmt.Println(num) fmt.Println(e) // 输出 0 unable to cast "hello" of type string to int64 123 nil
带 error 的版本其实就是在非 error 版的函数名结尾添加了一个 E,其结果也很好理解,这里不再展开细讲了。
2.2.3 很酷的东西
最后再来看一个我觉得很酷的东西:
var js interface{} = `{"name": "Jack", "gender": "male"}`
fmt.Println(cast.ToStringMap(js))
// 输出
map[gender:male name:Jack]cast 能直接将一个 JSON 字符串转换成 map!当然这一步其实用类型断言也可以做到,但 cast 的方式会更加优雅。
3 性能及原理
如果你只是想使用 cast,那么接下来的内容就可以忽略了;如果你还想深入了解一些 cast,可以看看这一节。
很多做后端开发的朋友会习惯性关心性能和原理,我也一样,所以早在我第一次接触使用 cast 时,我就去看了它的源码,然后……这样,我直接把上面我们用过的 ToInt 的相关源码列出来,大家自己看看就明白了:
// cast.go
// ToInt casts an interface to an int type.
func ToInt(i interface{}) int {
v, _ := ToIntE(i)
return v
}
// caste.go
// ToIntE casts an interface to an int type.
func ToIntE(i interface{}) (int, error) {
i = indirect(i) // 这个 indirect 函数里使用反射来获取 i 的 interface{} 值,代码不列了
// ...省略
switch s := i.(type) {
case int64:
return int(s), nil
case int32:
return int(s), nil
// ...省略
case string:
v, err := strconv.ParseInt(trimZeroDecimal(s), 0, 0)
if err == nil {
return int(v), nil
}
return 0, fmt.Errorf("unable to cast %#v of type %T to int64", i, i)
}
// ...省略
}明白了吧,没有什么技巧,依然是常规手段进行转换,只是它把各种情况都囊括了进来,做到了足够全面。
而且我们发现,带 error 的函数才是原始函数,不带 error 的只是一个封装后的便捷方式。
cast 的源码很短,只有两个文件,加起来不到 2000 行。
所以看到这里,cast 的性能问题就没什么值得讨论的了,一定高不到哪儿去。尤其在泛型已经实装了之后,泛型的性能要远超类型断言、反射之类的技术,因此大家在使用 cast 的时候也请视情况而定。
4 总结
cast 是我用了很多年的一个库了,早在泛型还八字没一撇的时候我就发现了这个库,那时我们的项目代码里充斥着许多 interface{} 和反射,cast 的确帮了我们很大的忙。尽管现在已经是泛型时代,go 语言可以用性能更佳的泛型替代许多以前只能用 interface{} 甚至反射实现的场景,但依然存在不少我们无法避免要用 interface{} 或类型转换的地方,这种时候,尤其是这段程序对性能不敏感时,cast 依然是一把万金油式的利器。
总结一下,cast 是一个用于类型转换的 golang 第三方库,它最大的特点是在类型转换时可以不 panic,而是将出现问题的地方转换成零值。当然,cast 也提供了带 error 的函数,以供开发者在适当情况下使用。cast 的性能可能会是一个问题,因此我们在使用时一定要选择合适的场景,避免由于滥用 cast 造成的性能瓶颈。
理论要掌握,实操不能落!以上关于《一文带你了解Golang中类型转换库cast的使用》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!
-
235 收藏
-
153 收藏
-
326 收藏
-
140 收藏
-
147 收藏
-
378 收藏
-
255 收藏
-
287 收藏
-
393 收藏
-
310 收藏
-
110 收藏
-
412 收藏
-
423 收藏
-
274 收藏
-
379 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习