惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Stack Overflow Blog
Stack Overflow Blog
WordPress大学
WordPress大学
罗磊的独立博客
S
Secure Thoughts
Schneier on Security
Schneier on Security
博客园 - Franky
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
爱范儿
爱范儿
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Hacker News: Ask HN
Hacker News: Ask HN
PCI Perspectives
PCI Perspectives
Google DeepMind News
Google DeepMind News
S
Security Affairs
SecWiki News
SecWiki News
博客园 - 聂微东
Security Archives - TechRepublic
Security Archives - TechRepublic
Google Online Security Blog
Google Online Security Blog
H
Heimdal Security Blog
S
Security @ Cisco Blogs
Engineering at Meta
Engineering at Meta
C
CXSECURITY Database RSS Feed - CXSecurity.com
Cloudbric
Cloudbric
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
V
Visual Studio Blog
P
Proofpoint News Feed
Project Zero
Project Zero
T
Threat Research - Cisco Blogs
Webroot Blog
Webroot Blog
Blog — PlanetScale
Blog — PlanetScale
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
W
WeLiveSecurity
Last Week in AI
Last Week in AI
月光博客
月光博客
Microsoft Azure Blog
Microsoft Azure Blog
M
MIT News - Artificial intelligence
有赞技术团队
有赞技术团队
S
Securelist
GbyAI
GbyAI
Application and Cybersecurity Blog
Application and Cybersecurity Blog
C
CERT Recently Published Vulnerability Notes
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Cyberwarzone
Cyberwarzone
B
Blog RSS Feed
P
Palo Alto Networks Blog
H
Hacker News: Front Page
D
Docker
雷峰网
雷峰网
Latest news
Latest news
Microsoft Security Blog
Microsoft Security Blog

咸糖 - 自律者自由

2025 年终总结:降噪、重构与长期主义 在新加坡和新山吃过最好的食物(持续更新) 写给还在迷茫的你:我的三本大学回忆 2024 年终总结 Neovim: No Crash Incremental Selection 2022 年终总结 使用 neovim 作为 PDE(个性化开发环境) shell 是一个不错的生产力工具 使用二八法则省力地学习 awk 肉身翻墙新加坡安顿指南 使用 Docker Compose 建立你自己的开发环境 关于编写可维护的代码的一些实践与想法 我为什么使用双向链接做笔记? 关于焦虑和拖延症 Golang: 如何处理日渐膨胀的 interface 使用番茄工作法来更好的利用你的时间 Unix 如何杀死一个进程和它的子孙进程? 使用 Mock 和 Interface 进行 Golang 单测 关于 Golang Slice 的一些细节 总结一些计算机常用的原则 重新学习英语语法 上班族近期小半年入门投资基金组合的学习与实践经历 疫情期间的肉身翻墙新加坡指南 About me 软技能:大厂底层员工打工指南 软技能:我是如何获取知识与信息的? 分布式的令牌桶算法的实现 实现一个AtomicInteger GC root 在哪里? 什么是 Minor GC/Major GC 漏桶算法的设计与实现 剑指offer 单例模式 TCP 针对面试学习 Actor 如何处理阻塞消息 Akka 源码解析 How to learn scala AES 需要限制 SEED 长度 Java 如何区分==与.equals()方法 2018年年度总结 Java 集合扩容
Golang: 让你的零值更有用
xiantang · 2022-01-16 · via 咸糖 - 自律者自由

文章目录

【注意】最后更新于 December 29, 2025,文中内容可能已过时,请谨慎使用。

Make the zero value useful。 –Go Proverbs

让我们从 Golang blog 开始吧:The zero value

当内存被分配来存储一个值时,无论是通过声明还是调用 make 或 new,并且没有提供明确的初始化,内存被赋予一个默认的初始化。这种值的每个元素都被设置为其类型的零值 (zero value):布尔值为 false,整数为 0,浮点数为 0.0,字符串为 "",指针、函数、接口、slice、channel 和 map 为 nil。这种初始化是递归进行的,因此,举例来说,如果没有指定值,结构数组的每个元素都将被归零。

这样将一个值设置为零值对程序的安全性和正确性做了很大的保证,同样也能很好的保证程序的可读性与简单性。这也就是 Golang 程序员口中的“让零值更有用 (Make the zero value useful)”。

零值 cheat sheet

类型 零值
bool false
int 0
float 0.0
string ""
pointer nil
function nil
slice nil
map nil
channel nil

同时零值的初始化是递归的,因此,如果没有指定值,结构数组的每个元素都将被归零。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
 gore --autoimport  
gore version 0.5.3  :help for help
gore> var a [10]int
gore> a
[10]int{
  0,
  0,
  0,
  0,
  0,
  0,
  0,
  0,
  0,
  0,
}

对于结构体也是如此,我们初始化一个引用 A 的 B 结构体,并且没有指定值,那么 B 的每个字段都将被归零。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
 gore --autoimport
gore version 0.5.3  :help for help
gore> type A struct { i int; f float64 }
gore> type B struct { i int; f float64; next A }
gore> new(B)
&main.B{
  i:    0,
  f:    0.000000,
  next: main.A{
    i: 0,
    f: 0.000000,
  },
}

note:

  • new:new(T) 返回一个指向新分配的 T 类型的 零值 的指针。
  • 使用的工具为 gore

零值的用法

上文已经介绍了什么是零值,这里我们来看看如何使用它们。

sync.Mutex

这里有一个关于 sync.Mutex 的例子,sync.Mutex 被设计成不用显式地去初始化他就可以直接通过零值来使用。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
package main

import "sync"

type MyInt struct {
        mu sync.Mutex
        val int
}

func main() {
        var i MyInt

        // i.mu is usable without explicit initialisation.
        i.mu.Lock()      
        i.val++
        i.mu.Unlock()
}

得益于零值的特性,Mutex 内部两个未导出的变量都会被初始化为零值。所以 sync.Mutex 的零值是一个未锁定的 Mutex。

1
2
3
4
5
6
7
8
// A Mutex is a mutual exclusion lock.
// The zero value for a Mutex is an unlocked mutex.
//
// A Mutex must not be copied after first use.
type Mutex struct {
 state int32
 sema  uint32
}

bytes.Buffer

另外一个例子是 bytes.Buffer,它的零值是一个空的 Buffer。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
package main

import "bytes"
import "io"
import "os"

func main() {
        var b bytes.Buffer
        b.Write([]byte("go go go"))
        io.Copy(os.Stdout, &b)
}

JSON omitempty

JSON 接收器也接受 omitempty 这个 flag,当输入的字段是 零值 时,接收器会忽略这个字段。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
  gore --autoimport          
gore version 0.5.3  :help for help
gore> type Person struct {
.....         Name string `json:"name"`
.....         Age  int    `json:"age"`
.....         Addr string `json:"addr,omitempty"`
..... }
gore> p1 := Person{
.....             Name: "taoge",
.....             Age:  30,
.....     }
main.Person{
  Name: "taoge",
  Age:  30,
  Addr: "",
}
gore> data, err := json.Marshal(p1)
...
gore> string(data)
"{\"name\":\"taoge\",\"age\":30}"

channel close

《Channel Axioms》中,也有一条与零值相关的规则,当 channel 关闭时,对被关闭的 channel 做<- 操作,总是立即返回 零值

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
package main

import "fmt"

func main() {
         c := make(chan int, 3)
         c <- 1
         c <- 2
         c <- 3
         close(c)
         for i := 0; i < 4; i++ {
                  fmt.Printf("%d ", <-c) // prints 1 2 3 0
         }
}

解决上述问题的正确的方式是使用 for loop:

1
2
3
4
for v := range c {
         // do something with v
}

map 中未找到对应 key 的 value

对于一个 map,如果没有找到对应的 key,那么这个 map 会返回对应类型一个零值。

1
2
3
4
5
6
7
8
 gore --autoimport
gore version 0.5.3  :help for help
gore> a := make(map[string]string)
map[string]string{}
gore> a["123"] = "456"
"456"
gore> a["000"]
""

解决这个问题的方法是返回多个值:

1
2
3
4
5
6
7
gore --autoimport
gore version 0.5.3  :help for help
gore> a := make(map[string]string)
map[string]string{}
gore> c,ok := a["000"]
""
false

对于不存在的 key,ok 的 value 将会变成 false。

总结

以上就是关于 零值 的一些经验总结。希望大家在设计代码的时候能够将 零值 更好的用起来,利用 零值 提供的特性来初始化一些变量。

相关链接

文章推荐

最后最后和大家分享一些最近在看的好文,想过用周刊的方式发送但是因为看的比较零散,就放在每篇博文的最后,希望大家能够收获。

文章作者 xiantang

上次更新 2025-12-29 (4c152d04)

赞赏支持

微信打赏 支付宝打赏