go的零值是语言规范强制保证的可预测默认状态,基础类型和结构体字段可安全使用,引用类型零值为nil但操作受限,new和make用途不同,接口nil判断需谨慎。

Go 的零值不是“没初始化”,而是每种类型都明确定义的、可预测的默认状态。 它不是靠运气填的,是语言规范强制保证的——声明即安全,但不等于“随便用”。关键在分清哪些能直接操作,哪些必须先初始化。
基础类型和结构体字段的零值:安全可用,但别误读语义
数值类型(int、float64)、bool、string 的零值分别是 0、false、"";结构体字段按此递归填充,比如 type User struct{ Name string; Age int } 的零值等价于 User{Name: "", Age: 0}。
- 这些值可以直接参与计算或比较,不会 panic ——
if u.Age == 0是合法且常见的默认逻辑判断 - 但
""和nil不同:u.Name == ""表示“空字符串”,而如果字段是*string,零值是nil,此时u.Name == nil才表示“未提供” - 配置结构体中常用
if cfg.Timeout != 0判断是否启用自定义超时,而不是检查== nil(int没有nil)
切片、map、channel、指针等引用类型的零值:统一为 nil,但行为差异极大
nil 是它们的零值,但“能读”和“能写”完全不是一回事。混淆 nil 切片和空切片([]int{})是最常踩的坑。
-
var s []int→s是nil:不能s[0] = 1,不能append(s, 1),但len(s)、cap(s)、for range s都安全 -
s := []int{}或s := make([]int, 0)→s是非-nil 空切片:可以append,可以遍历,长度为 0 -
var m map[string]int→m是nil:读m["k"]返回0, false(安全),但写m["k"] = 1会 panic -
var p *int→p是nil:解引用*p直接 panic,必须先赋值(如p = new(int)或p = &x)
new 和 make 怎么选?看返回值类型和用途
new(T) 和 make(T, ...) 都用于初始化,但职责完全不同,混用会导致语义错误或运行时 panic。
立即学习“go语言免费学习笔记(深入)”;
-
new(int)→ 返回*int,指向一个堆上分配的、值为0的int;适用于所有类型,但只做内存分配 + 零值填充 -
make([]int, 3)→ 返回[]int,是一个长度为 3、元素全为0的切片;仅支持[]T、map[K]V、chan T - 错误用法:
new([]int)返回的是*[]int(指向 nil 切片的指针),不是你想要的可 append 的切片 - 正确习惯:需要可写的 slice/map/chan,就用
make;只需要一个带零值的指针变量,就用new
零值机制省去了大量显式初始化,但它的真正价值不在“省事”,而在“明确性”——每个变量从诞生起就有定义良好的行为边界。最容易被忽略的一点是:nil 接口变量(var i interface{})可能内部存着非-nil 值(比如 i = &x),此时 i == nil 是 false;判断接口是否为空,不能只看 == nil,得用类型断言或反射确认底层值。










