讲解

变量是程序里存放数据的具名容器。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 的基本数据类型与类型转换。