大家好,我是建宇。上一篇文章给大家分享了《10+ 条 Go 官方谚语,你知道几条?》,今天再来说说第五句谚语,Makethezerovalueuseful(让零值有用),看看是什么意思。背景Go有一个比较特殊的概念,叫做零值。许多转换语言的学生一开始经常会感到困惑和不舒服。代码如下:funcmain(){variintvarffloat64varbboolvarsstringfmt.Printf("%v%v%v%q\n",i,f,b,s)}outputresult:00false""这会导致大家在定义各种数据库字段时纠结,还会说Go的零值,例如:整数的零值0,与数据库中的0枚举值冲突.或者在判断入场时如何区分?一时间无法理解为什么Go要定义这个零值来增加复杂度?官方解释是什么?Go核心团队的@DaveCheney在《What is the zero value, and why is it useful?》中详细解释了零值。将值设置为已知默认值的功能对于程序安全性和正确性很重要。可以让你的Go程序更加简洁紧凑。这就是Go程序员常说的“给你的结构一个有用的零值”。官方案例下面是Go官方给出的几个零值的例子,很有代表性。它们是:sync.Mutex。字节。缓冲。无功能Sync.Mutexsync.Mutex设计为无需显式初始化即可使用,这是可能的,因为sync.Mutex包含两个未导出的整数字段。通俗地说,由于零值的存在,只要声明了sync.Mutex,这些字段就会被设置为0(值会被初始化)。因此它可以开箱即用,无需显式初始化。以下代码:packagemainimport"sync"typeMyIntstruct{musync.Mutexvalint}funcmain(){variMyInt//i.mu无需显式初始化即可使用。i.mu.Lock()i.val++i.mu.Unlock()}Byte.Buffer为零值,bytes.Buffer在写入或读取时不需要手动初始化。开箱即用。下面的代码:)}注意:io.Copy需要一个io.Reader作为它的第二个参数,所以我们需要传递一个指向b的指针。切片定义中的切片,它的零值为nil。这意味着你不需要显式定义一个切片,直接声明它就可以使用了。下面的packagemainimport"fmt"import"strings"funcmain(){//s:=make([]string,0)//s:=[]string{}vars[]strings=append(s,"Hello")s=append(s,"world")fmt.Println(strings.Join(s,""))}Nilfunc您可以在具有nil值的类型上调用方法,这也是零值作为默认值功能之一。这一幕甚至一度让很多Go程序员认为是BUG,我什至专门写了一篇文章。这是可行的,实际上是零值的扩展用法。以下代码:packagemainimport"fmt"typeConfigstruct{pathstring}func(c*Config)Path()string{ifc==nil{return"/usr/home"}returnc.path}funcmain(){varc1*Configvarc2=&Config{path:"/export",}fmt.Println(c1.Path(),c2.Path())}总结了零值,尽管它是Go中的默认值。但它本质上不仅仅是默认的,它还在很多程序中为这种应用场景提供了很多方便的特性甚至是隐藏功能。希望对大家对零值的理解有进一步的帮助!Go书系列Go语言入门系列:初探Go项目实战Go语言编程之旅:深入使用Go做项目Go语言设计哲学:理解Go的Why与设计思维Go语言进阶之旅:走得更远GoSourceCode阅读更多想添加箭头语法,这更像PHP!Go错误处理的新思路?使用左手函数和表达式
