Go中const值须编译期确定;未显式指定类型时依右值推导,如const x=42推为int,const y=3.14为未定类型浮点常量;iota在每个const块首行重置为0,每行自增1,可用\_跳过或+iota偏移。

const 声明的基本写法和类型推导
Go 中 const 声明的值必须在编译期确定,不能是运行时计算结果。声明时若不显式指定类型,Go 会根据右值自动推导——但推导出的类型可能不是你想要的,尤其在数值运算或接口赋值场景下容易出错。
-
const x = 42推导为int(具体取决于平台,通常是int,而非int64) -
const y = 3.14推导为未定类型浮点常量(untyped float),可赋给float32或float64 -
const z int64 = 100显式指定类型,后续参与运算不会隐式转为int
常见坑:把未显式类型的整数常量直接传给需要 int64 参数的函数,会报 cannot use ... (type int) as type int64 错误——因为推导类型是 int,不是 int64。
iota 的行为和重置时机
iota 是 Go 的枚举计数器,只在 const 块内有效,且每遇到一个新 const 声明就重置为 0。它不是变量,不支持 ++ 或赋值,每次出现在新行就自增 1。
const ( A = iota // 0 B // 1 C // 2 ) const D = iota // 这里 iota 又从 0 开始 → D == 0
实用技巧:
立即学习“go语言免费学习笔记(深入)”;
- 跳过某值:用
_ = iota占位 - 偏移起始值:
const Start = iota + 10 - 按位组合:
Read = 1 、Write、Exec会依次得到 1, 2, 4
const 与 var 在包级作用域的差异
包级 const 和 var 都可导出(首字母大写),但本质不同:const 是编译期字面量,不占运行时内存;var 是运行时分配的变量,哪怕值相同也会有独立地址。
这意味着:
- 多个
const引用同一字符串字面量,它们共享底层数据(无内存开销) - 而
var s = "hello"每次声明都可能产生新字符串头(虽底层数据可能复用,但语义上是独立变量) -
const不能取地址:&MyConst编译报错cannot take the address of MyConst
所以配置项如 API 地址、超时毫秒数,优先用 const;需要修改或取地址的,才用 var。
跨包使用 const 的注意事项
Go 中 const 不像 C 的宏,它没有文本替换行为。跨包引用时,只要导出名首字母大写,就能正常使用,但要注意类型一致性。
例如在 pkg/a/a.go 中定义:
package a const MaxRetries = 3
在 main.go 中引用:
import "your-module/pkg/a"
func main() {
_ = a.MaxRetries // 类型是 int,不是 int64 或 uint
}
关键点:
- 如果
a.MaxRetries被其他包当作int64使用,需显式转换:int64(a.MaxRetries) - 不要依赖未导出 const(小写)跨包使用,Go 编译器会直接拒绝
- const 值被内联进调用方二进制,因此修改 const 后必须重新编译所有引用它的包
真正容易被忽略的是最后一点:const 看似“静态”,实则影响构建依赖链——改一个公共 const,所有 import 它的包都得重编,CI/CD 中若缓存策略不当,可能漏掉更新。










