结构体变量声明才是分配内存、产生可用实例的关键步骤;var声明零值初始化最安全,:=用于函数内简洁推导,new()和&Type{}获取零值指针,数组切片需避C风格陷阱,字段首字母大小写决定导出性。

struct 类型本身只是蓝图,声明变量才是分配内存、产生可用实例的关键步骤。Go 里没有“类实例化”概念,只有“结构体变量声明”,方式灵活但容易混淆——尤其新手常把类型定义当变量用,或误用 C 风格写法(比如 Student[5]),直接报错。
用 var 声明并零值初始化
最显式、最安全的方式,适合包级变量或需要明确类型时使用。字段全部设为对应类型的零值(string → "",int → 0,bool → false):
-
var s Student:声明变量s,类型为Student,所有字段自动为零值 -
var s *Student:声明指针变量,值为nil,尚未指向任何内存 - 不能写成
var s Student{}—— 这是语法错误;{}只能用于复合字面量初始化,不能跟在var后作初始化器
用短变量声明 := 创建并初始化
函数内最常用,编译器自动推导类型,简洁但受限于作用域:
-
s := Student{}:创建一个零值Student实例,等价于var s Student -
s := &Student{}:创建并取地址,得到*Student指针,字段全零值 -
s := Student{Name: "Alice", Age: 25}:只初始化部分字段,未写的字段仍为零值 - 注意:
:=不能用于包级作用域,否则编译失败
用 new() 或 &Type{} 获取指针
两者效果一致,都返回指向新分配零值内存的指针:
立即学习“go语言免费学习笔记(深入)”;
-
s := new(Student):调用new,返回*Student,所有字段为零值 -
s := &Student{}:更常见,语义更清晰,也返回*Student - 区别在于可读性:
&Student{}支持字段初始化(如&Student{Name:"Bob"}),new(Student)不支持 - 无论哪种,后续访问字段都统一用
s.Name(Go 自动解引用),无需写(*s).Name
声明结构体数组或切片要避开 C 风格陷阱
Go 不允许在类型后直接跟方括号声明数组变量(如 Student[3] 是非法语法):
- 正确数组声明:
var states [3]State或states := [3]State{} - 正确切片声明:
states := make([]State, 0, 5)或states := []State{} - 错误写法:
var states State[3]、states := State[3]{}—— 编译器会报syntax error: unexpected [ - 数组长度是类型的一部分,
[3]State和[5]State是两个完全不同的类型
最容易被忽略的是:结构体字段首字母大小写直接决定是否可导出(即能否被其他包访问)。声明变量本身不解决可见性问题,但若结构体字段小写(如 name string),哪怕变量是公开的,外部也无法读写该字段——这和声明方式无关,是类型定义阶段就锁定的约束。


















