为何包含指针的interface在指针更新后未同步更新?
Go中修改指针变量指向后interface未同步更新的原因及解决办法
原因分析
问题核心在于Go的interface赋值逻辑:当你把*Rect类型的rA赋值给any类型的r1时,interface内部会复制rA的指针值,而不是保存指向rA变量的引用。
换句话说:
r1 = rA执行后,r1里存的是rA当时指向的内存地址(比如输出里的0xc00001c030),这是一个独立的副本,和rA变量本身没有绑定关系。- 后续通过
r1Adr修改的是rA变量的指向,但r1里的指针副本已经固定,不会自动同步变化。
解决办法
要让r1能跟随rA的指向变化,你需要让r1存储指向rA变量的指针(也就是**Rect类型),而不是rA的指针值本身。这样当rA的指向改变时,通过r1解引用就能拿到最新的地址。
修改后的代码示例:
type Rect struct { width int } func main() { rA := new(Rect) rB := new(Rect) var r1, r2, r1Adr, r2Adr any r1 = &rA // 存储指向rA变量的指针,而非rA的值 r2 = rB r1Adr = &rA r2Adr = &rB *r1Adr.(**Rect) = *r2Adr.(**Rect) // 打印时需解引用r1获取最新的Rect地址 fmt.Printf("%p, %p, %p, %p, %p, %p", rA, rB, *r1.(**Rect), r2, *r1Adr.(**Rect), *r2Adr.(**Rect)) }
此时输出会全部同步为rB的地址,r1解引用后的值会和rA保持一致。
需要注意:现在r1的底层类型是**Rect,所以使用时需要多一次解引用操作,才能拿到实际的*Rect指针。
内容的提问来源于stack exchange,提问作者gabetucker22
相关产品推荐
相关产品推荐

