Go 中 const 值没有内存地址,因其在编译期被直接替换为字面值,不分配运行时内存,故无法取地址,任何 &constValue 都会触发编译错误;需用 var 声明变量后取址。
const 值没有内存地址因为 const 在编译期就被替换成字面值,不分配运行时内存。Go 编译器会把所有对常量的引用直接内联为对应值(比如 const pi = 3.14159,后续写 &pi 时,编译器根本找不到一个“变量”来取地址)。
这和 C/C++ 不同:C 的 const 变量仍占内存(只是加了只读修饰),而 Go 的 const 是纯编译期符号,连符号表里都不一定保留。
&constValue 会直接报错 cannot take the address of ...
尝试对任何 const 取地址都会触发编译错误,无论类型是 int、string 还是自定义类型:
const name = "gopher" ptr := &name // 编译错误:cannot take the address of name
常见误操作场景:
立即学习“go语言免费学习笔记(深入)”;
fmt.Printf("%s", &name))→ 改用 &temp(先赋值给变量)Config{Title: &name})→ 必须先声明变量:title := name; Config{Title: &title}
如果确实需要指针,唯一合法方式是用 var 显式声明变量,并初始化为该常量:
const mode = 0644 var modeVar = mode permPtr := &modeVar // ✅ 合法
注意点:
var modeVar = constValue 然后立即取地址——必须分两步或确保变量已分配空间:= 也有效:modeVar
:= mode; ptr := &modeVar
Go 把常量视为“值本身”,不是“可寻址实体”。这种设计带来两个实际好处:
&42 或 &"hello" 在其他语言中行为不一)const)和“只读存储位置”(var + const 初始化)真正容易被忽略的是:哪怕常量类型实现了接口,也不能直接取地址转为接口指针——必须经过变量中转。这点在写泛型约束或反射逻辑时特别容易踩坑。