讲解
变量是程序里存放数据的具名容器。Go 有两种声明方式:完整形式 var 名字 类型 = 初值,以及函数内部常用的短声明 名字 := 初值。短声明让编译器根据初值自动推断类型,写起来最顺手,是日常代码的主流写法;var 形式则用于需要显式指定类型、或先声明后赋值的场景。
Go 有一条让其他语言程序员起初不适应的硬规则:声明了变量就必须使用,否则编译报错。这和「未使用的 import 报错」一样,是语言在强迫你保持代码干净。确实需要丢弃某个值时,用空白标识符 _ 接收,比如只要多返回值里的一个。
另一个重要规则是「零值」:声明变量时不给初值,Go 不会留一个随机垃圾值,而是自动赋该类型的零值——数字是 0、字符串是空串、布尔是 false、指针是 nil。零值机制让「声明后忘记初始化」这类 bug 在 Go 里大幅减少。多重赋值 a, b = b, a 可以一行完成交换,是 Go 的标志性写法之一。
示例
var 声明与各类型的零值:
package main
import "fmt"
func main() {
var name string
var age int
var ok bool
fmt.Printf("零值: name=%q age=%d ok=%v\n", name, age, ok)
var city = "北京" // 省略类型,自动推断
var x, y int = 1, 2
fmt.Println(city, x, y)
}
短声明、多重赋值与空白标识符:
package main
import "fmt"
func main() {
a, b := 1, 2
a, b = b, a // 多重赋值,一行完成交换
fmt.Println("交换后:", a, b)
n, _ := fmt.Println("Println 返回写入的字节数和 error")
fmt.Println("上一行输出了", n, "个字节")
width, height := 10, 20
fmt.Println("面积:", width*height)
}
常见坑
- 短声明用在函数外::= 只能在函数内部使用,包级别的变量必须用 var。新手常在文件顶部写 name := "x" 然后对着报错发懵。
- 重复短声明:同一作用域里 name := 只能出现一次,再次写会报「no new variables on left side」。第二次起用 = 赋值;但如果 := 左边至少有一个新变量,编译器允许旧变量被重新赋值。
- 以为未赋值变量是 nil:只有指针、切片、map、通道、函数、接口的零值是 nil,int 是 0、string 是空串。对 0 值数字调用方法没问题,对 nil 指针解引用才会 panic。
- 屏蔽(shadow)外层变量:内层作用域用 := 声明同名变量会「盖住」外层变量,内层修改不影响外层,if 语句块里尤其常见。调试时变量值「莫名其妙没变」多半是这个原因。
小结
var 完整声明、:= 短声明推断类型;未初始化变量自动得到零值;声明必用、丢弃用 _。下一节认识 Go 的基本数据类型与类型转换。