In our discussion yesterday, @bradfitz asked if weak pointers made it possible to maintain a map of expensive derived information about something without preventing the GC of that something. Here is a worked example of how weak pointer enables that:
var cache struct { mu sync.Mutex m map[weak.Pointer[Foo]]*derived } func init() { cache.m = make(map[weak.Pointer[Foo]]*derived) } func cached(f *Foo) *derived { cache.mu.Lock() defer cache.mu.Unlock() p := weak.Make(f) d := cache.m[p] if d != nil { return d } d = expensiveComputation(f) cache.m[p] = d runtime.AddCleanup(f, deleteP, p) } func deleteP(p weak.Pointer[Foo]) { cache.mu.Lock() defer cache.mu.Unlock() delete(cache.m, p) }
I am assuming runtime.AddCleanup from #67535, which is guaranteed to work with any pointer f. (SetFinalizer might break things if f already had a finalizer, or if f was inside another object.)
-- @rsc golang/go#67552 (comment)