在介绍Go 1.23引入的unique包的《Go unique包:突破字符串局限的通用值Interning技术实现》一文中,我们知道了unique包底层是基于internal/weak包实现的,internal/weak是一个弱指针功能的Go实现。所谓弱指针(Weak Pointer,也称为弱引用)是与强指针相对而言的,强指针(Strong Pointer,也可称作强引用)就是下面代码片段中的这种常规指针:
var p *T = new(T) // 假设T类型对象被分配到堆上
只要p指向堆上的T对象,那么T对象就无法被GC回收。但弱指针并非如此,它也可以指向堆上的某个内存对象(比如T类型对象),但它无法像强指针那样阻止GC回收该对象。
Go unique包的实现者Michael Knyszek近期提议在标准库引入weak包[3](实际上是将internal/weak公开暴露给Go开发者),该提议被Russ Cox代表的Go提案评审委员会所接受,最早将于Go 1.24版本落地。
在这篇短文中,我们来前瞻一下weak包的API设计、原理、应用场景以及社区对该提案一些观点。
注:weak包尚未落地,本文中的代码在Go 1.23中均无法运行,可以视作伪代码。
1. weak包的API
weak包的核心是Pointer[T]类型,它代表了对类型T的弱指针。以下目前Michael Knyszek为weak包设计的主要API:
type Pointer[T any] struct { ... }
func Make[T any](ptr *T "T any") Pointer[T]
func (p Pointer[T]) Value() *T
Make函数用于创建一个弱指针,而Value方法则用于获取弱指针指向的实际值。如果原始对象已被垃圾回收,Value方法将返回nil。这个设计秉承了Go一贯的简洁,允许开发者轻松创建和使用弱指针,同时保持了Go语言的类型安全特性。
2. weak包弱指针的工作原理
在开篇时,我已经对弱指针的作用做了简单说明,这里结合上述weak包的API和提案中的设计原理再扩展一下。
弱指针的核心思想是允许引用内存而不阻止垃圾回收器回收它。垃圾回收器在回收对象时,会自动将所有指向该对象的弱指针设置为nil。这确保了弱指针不会产生悬空引用(dangling pointer)。
下图是weak包弱指针的工作原理示意图,展示了weak pointer的核心工作原理,包括间接对象的使用和垃圾回收时的行为:

最低0.47元/天 解锁文章
1477

被折叠的 条评论
为什么被折叠?



