
Go语言中无法直接对函数调用结果取地址(如 &getAString()),因为返回值是临时、不可寻址的值;必须先将其赋给一个局部变量,再对该变量取地址。
go语言中无法直接对函数调用结果取地址(如 `&getastring()`),因为返回值是临时、不可寻址的值;必须先将其赋给一个局部变量,再对该变量取地址。
在Go中,& 运算符只能作用于可寻址(addressable) 的操作数。根据Go语言规范,可寻址值包括:变量、指针解引用(*p)、切片索引(s[i])、结构体字段(x.f,且 x 可寻址)、数组索引(a[i],且 a 可寻址),以及(例外)复合字面量(如 &struct{X int}{1})。而函数调用表达式(如 getAString())返回的是一个临时值(r-value),它没有内存地址,也不属于上述任何可寻址类别,因此 &getAString() 会导致编译错误:
cannot take the address of getAString()
✅ 正确做法是引入一个局部变量,使返回值“落地”为可寻址的左值(l-value):
func getAStringPointer() *string {
s := getAString() // s 是一个可寻址的局部变量
return &s // ✅ 合法:&s 指向栈上分配的 string 值
}
func getAString() string {
return "hello"
}
⚠️ 注意事项:
- 局部变量
s在函数返回后仍可能被安全引用——Go编译器会自动将其逃逸分析(escape analysis) 到堆上,确保返回的指针有效; - 不要试图通过
&"literal"或&42等方式绕过限制:除复合字面量外,基本类型字面量本身不可取地址; - 若需频繁返回字符串指针,可考虑直接返回
*string类型的参数或使用new(string)初始化:
func getAStringPointer() *string {
return new(string) // 等价于 p := new(string); return p
}
总结:Go的设计强调内存安全与语义清晰,禁止对临时值取地址,正是为了防止悬垂指针和未定义行为。显式引入中间变量不仅符合语言规则,也提升了代码可读性与可维护性。











