为什么 uintptr 不能替代受 GC 追踪的指针?
- 整数本质:
uintptr 只是一种无符号整数,数值宽度足以保存当前平台的地址位模式;
- GC 语义:
uintptr 不被垃圾回收器当作指针追踪;
- 生命周期风险: 将指针转为
uintptr 后长期保存,不能阻止目标被移动、回收或失效;
- 使用限制: 普通业务代码不应把
uintptr 当作安全指针使用;
| 形式 | GC 是否按指针追踪 | 是否支持普通指针算术 |
|---|
| Go pointer | 是 | 否 |
uintptr | 否 | 作为整数参与运算 |
- 转换原则: 指针与
uintptr 的往返转换必须遵守 unsafe.Pointer 文档允许的模式,不能凭数值相同推断地址仍然有效;
- 替代方案: 能用 slice、索引、类型安全 pointer 或标准库 API 表达时,不使用
uintptr;
指针限制有哪些? 何时需要 unsafe?
- 指针算术: Go 不支持普通指针加减运算;
- 临时值取址: 不可对不可寻址的临时结果直接取地址;
- 安全边界: 需要底层地址运算时通常涉及
unsafe;
- 可寻址性: 变量有可取出的地址;函数返回的普通值不能直接取址,但结构体复合字面量
&T{...} 是语法允许的特例;