Go中指针类型是*T而非独立关键字,声明为var p *int;map元素不可取地址因底层可能移动,需先拷贝再取址;nil指针默认值安全但解引用会panic;是否用指针取决于是否需修改原值或避免复制开销。

Go里声明指针变量的语法是 *T
Go中指针类型不是独立关键字,而是由星号 * 和基础类型组合而成。比如 *int 表示“指向 int 的指针”,*string 表示“指向 string 的指针”。它本身是一个类型,不是修饰符。
常见错误是写成 int*(C风格)或误以为 * 是声明时的运算符——其实它只是类型字面量的一部分。
- 正确写法:
var p *int、q := new(string)、r := &x(其中x是已声明变量) -
new(T)返回*T,但只做零值分配,不支持带参数初始化 - 用
&取地址时,操作数必须是可寻址的:不能对字面量、函数返回值、map元素(除非先赋给局部变量)直接取地址
为什么不能对 map[string]int 的值直接取地址
因为 map 的底层实现中,值可能被重新分配或移动,Go 禁止获取 map 元素的地址以避免悬垂指针。你看到的错误类似:cannot take the address of m["key"]。
- 绕过方式:先把值拷贝出来,再取地址,例如
v := m["k"]; ptr := &v - 如果真需要指针语义,考虑把 map 值类型设为指针,如
map[string]*int - 切片元素可以取地址(只要切片本身可寻址),这是和 map 的关键区别
nil 指针在 Go 中的默认行为
所有未初始化的指针变量默认值都是 nil,不是随机地址。解引用 nil 指针会 panic,错误信息是 panic: runtime error: invalid memory address or nil pointer dereference。
立即学习“go语言免费学习笔记(深入)”;
- 安全做法:使用前检查是否为
nil,尤其在函数参数或结构体字段中接收指针时 - 结构体中的指针字段不会自动初始化,需显式赋值或用
&T{}构造 - 注意
== nil比较只对指针类型安全;接口类型即使底层是*T,也不能直接和nil比较(要判空需用if v == nil且v类型是具体指针)
什么时候该用指针,什么时候不该用
核心判断依据是:是否需要修改原值,或是否想避免复制开销。
- 传参时:小类型(
int、bool、[3]int)通常值传更高效;大结构体、切片、map、channel 本身已是引用语义,一般不额外用指针 - 方法接收者:想修改接收者内容时必须用指针接收者(
func (p *Person) SetName(n string));否则值接收者只能改副本 - 切片虽是引用类型,但其头信息(ptr/len/cap)是值传递的,所以扩容后原变量不受影响——这时若需同步变化,就得传
*[]T
nil 判定逻辑。


















