一文带你了解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 收藏
-
233 收藏
-
322 收藏
-
181 收藏
-
316 收藏
-
244 收藏
-
300 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 507次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 484次学习