Go语言精进之路读书笔记第11条——尽量定义零值可用的类型
11.1 Go类型的零值#
Go语言规范中关于变量默认值的描述:
当通过声明或调用new为变量分配存储空间,或者通过复合文字字面量或调用make创建新值,且不提供显式初始化时,Go会为变量或值提供默认值。
Go规范定义的内置原生类型的默认值(零值):
- 所有整型类型:0
- 浮点类型:0.0
- 布尔类型:false
- 字符串类型:""
- 指针、interface、切片(slice)、channel、map、function:nil
Go的零值初始是递归的,即数组、结构体等类型的零值初始化就是对其组成元素逐一进行初始化。
11.2 零值可用#
Go从诞生以来就一直秉承着尽量保持“零值可用”的理念,因此我们可以针对符合这种理念的类型的声明了但未初始化的变量,直接调用其类型的方法。
特点
- Go语言零值可用的理念给内置类型、标准库的使用者带来很多便利。不过Go并非所有类型都是零值可用的,并且零值可用也有一定的限制,
比如:
// 1.在append场景下,零值可用的切片类型不能通过下标形式操作数据
var s []int
s[0] = 12 // 报错!
s = append(s, 12) // 正确
// 2.像map这样的原生类型也没有提供对零值可用的支持
var m map[string]int
m["go"] = 1 // 报错!
m1 := make(map[string]int)
m1["go"] = 1 // 正确
// 3.零值可用的类型要注意尽量避免值复制,可以用指针方式来传递值
var mu sync.Mutex
mu1 := mu // 错误: 避免值复制
foo(mu) // 错误: 避免值复制
foo(&mu) // 正确
- 保持与Go一致的理念,给自定义的类型一个合理的零值,并尽量保持自定义类型的零值可用,这样我们的Go代码会更加符合Go语言的惯用法。
标准库里的例子
var p *net.TCPAddr
fmt.Println(p) //输出:<nil>
// 我们看到Go标准库在定义TCPAddr类型及其方法时充分考虑了“零值可用”的理念,使得通过值为nil的TCPAddr指针变量依然可以调用String方法。
/*
func (a *TCPAddr) String() string {
if a == nil {
return "<nil>"
}
ip := ipEmptyString(a.IP)
if a.Zone != "" {
return JoinHostPort(ip+"%"+a.Zone, itoa(a.Port))
}
return JoinHostPort(ip, itoa(a.Port))
}
*/
作者:brynchen
出处:https://www.cnblogs.com/brynchen/p/18002106
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
标签:
Go语言精进之路
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具