跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

Golang常量const为什么不能取地址

Go 中 const 值没有内存地址,因其在编译期被直接替换为字面值,不分配运行时内存,故无法取地址,任何 &constValue 都会触发编译错误;需用 var 声明变量后取址。 Go 中
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语言免费学习笔记(深入) ”; C函数速查手册(CHM版) C函数速查手册(CHM版) 下载 想传指针给函数(比如
fmt.Printf("%s", &name)
)→ 改用
&temp
(先赋值给变量) 初始化结构体字段为指针(
Config{Title: &name}
)→ 必须先声明变量:
title := name; Config{Title: &title}
在切片或 map 中存常量地址 → 不可行,需用变量兜底 替代方案:用变量包装常量再取地址 如果确实需要指针,唯一合法方式是用
var
显式声明变量,并初始化为该常量:
const mode = 0644 var modeVar = mode permPtr := &modeVar // ✅ 合法
注意点: 不能写成
var modeVar = constValue
然后立即取地址——必须分两步或确保变量已分配空间 短变量声明
:=
也有效:
modeVar := mode; ptr := &modeVar
这种变量不会被编译器优化掉,哪怕值和常量完全一样 为什么设计成这样?性能与语义一致性 Go 把常量视为“值本身”,不是“可寻址实体”。这种设计带来两个实际好处: 避免对字面值取地址引发的歧义(比如
&42
或
&"hello"
在其他语言中行为不一) 让编译器能更激进地做常量折叠和内联,减少不必要的内存分配 强制开发者区分“不可变值”(
const
)和“只读存储位置”(
var + const
初始化) 真正容易被忽略的是:哪怕常量类型实现了接口,也不能直接取地址转为接口指针——必须经过变量中转。这点在写泛型约束或反射逻辑时特别容易踩坑。

相关文章