Go语言中为什么不能直接对类型转换结果使用取地址运算符&?
结论
第二种写法语法不符合Go语言规范,属于非法写法,编译会直接报错。
核心原因
Go语言对&取地址操作符的使用有明确约束:只能对「可寻址(addressable)」的表达式取地址,类型转换产生的结果属于临时值(右值),不属于可寻址范围。
可寻址的表达式仅包含以下几类:
- 已声明的局部变量/全局变量
- 指针的解引用结果
- 数组/切片的元素
- 可寻址结构体的成员字段
- 显式声明的复合字面量(Go专属特例,隐式临时值不适用)
string(byteArray)是类型转换生成的临时值,没有固定的内存地址,Go直接从语法层面禁止对这类值取地址,核心目的有两个:
- 避免悬空指针风险:临时值的生命周期仅存在于当前表达式执行阶段,如果允许取地址,后续访问该指针时很可能指向已经被回收的内存空间,引发不可预期的错误
- 降低不必要的性能开销:如果允许对任意临时值取地址,Go runtime需要额外判断大量临时值是否需要逃逸到堆上,会增加GC压力,也会降低栈内存的利用效率
替代方案
如果想省去显式声明变量的步骤,可以通过泛型工具函数实现(要求Go 1.18及以上版本):
// 泛型取地址工具函数 func ptr[T any](v T) *T { return &v } func example() *string { byteArray := someFunction() return ptr(string(byteArray)) }
该写法合法:临时值会被拷贝为工具函数的入参局部变量,局部变量属于可寻址范围,返回的指针指向的是逃逸到堆上的合法内存地址,不会出现生命周期问题。
内容的提问来源于stack exchange,提问作者jws
相关产品推荐
相关产品推荐

