跳到主要内容

uintptr 与指针边界

为什么 uintptr 不能替代受 GC 追踪的指针?​

  • 整数本质: uintptr 只是一种无符号整数,数值宽度足以保存当前平台的地址位模式;
  • GC 语义: uintptr 不被垃圾回收器当作指针追踪;
  • 生命周期风险: 将指针转为 uintptr 后长期保存,不能阻止目标被移动、回收或失效;
  • 使用限制: 普通业务代码不应把 uintptr 当作安全指针使用;
形式GC 是否按指针追踪是否支持普通指针算术
Go pointer是否
uintptr否作为整数参与运算
  • 转换原则: 指针与 uintptr 的往返转换必须遵守 unsafe.Pointer 文档允许的模式,不能凭数值相同推断地址仍然有效;
  • 替代方案: 能用 slice、索引、类型安全 pointer 或标准库 API 表达时,不使用 uintptr;

指针限制有哪些? 何时需要 unsafe?​

  • 指针算术: Go 不支持普通指针加减运算;
  • 临时值取址: 不可对不可寻址的临时结果直接取地址;
  • 安全边界: 需要底层地址运算时通常涉及 unsafe;
x := 10
p := &x
*p = 20 // 修改目标,而不是对地址做 p+1
// p++ // 编译错误:普通 Go 指针不能做算术
  • 可寻址性: 变量有可取出的地址;函数返回的普通值不能直接取址,但结构体复合字面量 &T{...} 是语法允许的特例;