Go中变量和常量用法由语境强制决定:包级变量只能用var,函数内var可零值声明而:=需初始化且不可重声明;const中iota是编译期递增常量生成器,每行+1,可跳过或偏移。

var 声明必须出现在函数外或函数内,但作用域和限制完全不同
包级变量(即函数外)只能用 var,不能用 :=;函数内两者都可用,但行为差异极大:var 允许只声明不初始化(自动给零值),:= 必须同时声明+初始化,且不能重复声明同一变量名。
-
var在函数外:唯一合法方式,比如配置、全局计数器var MaxRetries = 3 -
var在函数内:适合需要零值起步的场景,如var buf bytes.Buffer(bytes.Buffer零值可直接用) -
:=只能在函数内:简洁,但连续写两遍i := 1第二行会报错no new variables on left side of := - 混用风险:已有
var i int,后面再写i := 2不是赋值,而是新声明——但因变量已存在,编译直接失败
const 块里的 iota 不是“自增变量”,而是编译期常量生成器
iota 看起来像循环变量,实际是 Go 编译器在 const 块内从 0 开始的计数器,每行递增 1。它不占运行时内存,也不可修改,一旦手动赋值(如 A = 10),后续行的 iota 就中断递增,保持上一行的值。
- 基础用法:
const (A = iota; B; C)→A=0, B=1, C=2 - 跳过值:用
_占位,const (A = iota; _; B)→A=0, B=2 - 偏移/掩码:常配合位运算,
const (Read = 1 → <code>Read=1, Write=2, Exec=4 - 错误高发点:把
iota写在函数里(非法)、或试图fmt.Println(iota)(编译报错,iota不是变量)
短变量声明 := 的三个硬性边界
:= 是 Go 最常用也最容易误用的语法。它不是“简写版 var”,而是一套独立规则:必须在函数作用域、左侧至少有一个新变量、不能用于包级声明。
- 新变量判定看左侧:
a, b := 1, 2合法;a, b := 1, 2; a, c := 3, 4报错,因为a已存在,c是新变量但a不是,不满足“至少一个新变量” - 类型由右值决定:
s := "hello"→string;f := 3.14→float64(不是float32) - 无法声明指针/接口等需显式类型的场景:比如
var w io.Writer不能写成w := new(bytes.Buffer)(类型是*bytes.Buffer,非io.Writer) - 常见坑:
if err := doSomething(); err != nil { ... }中的err是新变量,但如果外层已有err,这里就变成新声明而非赋值——错误被静默吞掉
变量未使用和常量未导出是编译期强制检查项
Go 编译器对“死代码”零容忍:局部变量声明后没被读写,直接报错 xxx declared and not used;包级 const 或 var 若首字母小写且没被同包其他代码引用,也会触发 xxx is unused。
立即学习“go语言免费学习笔记(深入)”;
- 调试时临时注释掉某行,导致变量未使用?删掉声明,别留着注释代码
- 想定义一个包内私有常量但暂时没用到?加个空行调用:
_ = myConst(虽不优雅,但能过编译) - 导出常量必须大写开头:
const ServerAddr = "localhost:8080"可被其他包引用;const serverAddr = "..."只能在本包用,且若无引用就会被报 unused - 注意
nil不是常量关键字而是预定义标识符,不能重新声明为变量名
var、:=、const 这三者各自生效的上下文边界太细——漏掉任一条件,编译器就立刻打断你。写之前先问一句:这行在哪儿?谁用?要不要导出?答案定了,写法自然就唯一了。


















