只有在声明新变量时必须用 :=;它是声明加赋值的组合操作,已存在变量再用会报错;函数内首次定义或 for 循环初始化迭代变量时必须使用。

什么时候必须用 := 而不是 =
只有在**声明新变量**时才能用 :=;它本质是「声明 + 赋值」的组合操作,不是单纯的赋值。如果变量已经存在,再写 a := 42 会报错:no new variables on left side of :=。
- 函数内首次定义变量:用
:=最省事,比如name := "Alice" - for 循环里初始化迭代变量:必须用
:=,如for i := 0; i - if/for/switch 的初始化语句中:只能用
:=,例如if err := doSomething(); err != nil - 不能在包级作用域(全局)使用
:=—— 那里只能用var
:= 会自动推导类型,但推导错了怎么办
Go 的类型推导很直接:看右边值的字面量或表达式类型。比如 n := 42 推出 int,f := 3.14 推出 float64,s := "hi" 推出 string。问题常出在数字字面量上:
- 想用
int32却写了x := 100→ 实际是int,和函数参数类型不匹配就报错 - 调用需要
uint的 API 时,i := 5不行,得显式写var i uint = 5或i := uint(5) - 从 map 取值并判断是否存在:
v, ok := m["key"]是惯用法,这里ok类型固定为bool,不用操心
多个变量一起声明时,:= 的坑在哪
看起来方便:a, b, c := 1, "hello", true,但容易误伤已有变量:
- 只要左边**至少有一个新变量**,整条语句就合法;其余已存在的变量会被重新赋值 —— 这是 Go 的设计,不是 bug
- 比如已有
err := io.EOF,又写data, err := readData(),只要data是新的,err就会被覆盖(类型还必须兼容) - 如果左边全是已有变量,比如
a, b := 1, 2但a和b都已声明过,就会编译失败 - 建议:多变量声明时,先扫一眼左边有没有新名字;不确定就拆成
var声明 +=赋值
为什么有些地方死活不能用 :=
除了包级变量,还有几个硬性限制:
- 结构体字段初始化不能用:
user := User{name: "A", age: := 25}❌ —— 字段赋值只能用= - 函数返回值接收时,如果全都是已有变量,不能用:
a, b := f()要求a或b至少一个未声明过 - 类型断言后赋值:
s, ok := interface{}("x").(string)✅ 可以;但s := interface{}("x").(string)❌ 报错,因为类型断言表达式本身不是“单个值”,Go 规定这种场景必须用两变量形式 - channel receive 也类似:
v, ok := 是常见写法;单独 <code>v := 没问题,但那是纯接收,不带关闭状态检查
最常被忽略的是:短变量声明只存在于函数内部,且每次出现都必须带新变量——它不是语法糖,是作用域和类型检查强绑定的机制。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











