为什么我的界面中包含指针的部分在指针更新后没有更新?

huangapple go评论97阅读模式
英文:

Why is my interface containing a pointer not updating after the pointer is updated?

问题

我遇到的问题有很多限制,所以我将其大大简化为包含以下内容的不自然代码:

  • 一个名为Rect的结构体
  • rArB都指向一个新的Rect对象
  • r1r2,它们是包含rArB的接口
  • r1Adrr2Adr,它们是包含rArB的地址的接口

我想要执行rA = rB,但在声明变量后不允许引用rArB

(注意:你可能会认为这很容易,你只需执行*r1.(*Rect) = *r2.(*Rect)。然而,这种方法的问题在于它不会将rA指向rB的Rect对象,它只是将rB的Rect值克隆到rA的Rect中。因此,我必须解引用指向rAr1Adr)的指针,并将其赋值给rB,以使rA指向与rB相同的Rect对象。)

以下是我尝试的方法:

type Rect struct {
	width int
}

func main() {
	rA := new(Rect)
	rB := new(Rect)

	var r1, r2, r1Adr, r2Adr any
	r1 = rA
	r2 = rB
	r1Adr = &rA
	r2Adr = &rB

	*r1Adr.(**Rect) = *r2Adr.(**Rect)

    // 打印存储的每个Rect对象的地址
	fmt.Printf("%p, %p, %p, %p, %p, %p", rA, rB, r1, r2, *r1Adr.(**Rect), *r2Adr.(**Rect))
}

0xc00001c038, 0xc00001c038, 0xc00001c030, 0xc00001c038, 0xc00001c038, 0xc00001c038

PLAYGROUND: https://go.dev/play/p/VnQwx6V7DNa

从输出中可以看出,rA正确更新为rB,而r1Adrr2Adr完全反映了这一点。然而,r1rA没有更新为rB,这可以通过其输出的不同来证明。为什么会这样?如果rA被更新为rB,并且如果r1存储了rA,那么为什么r1指向的rA没有更新为rB

如果能在不改变r1为接口的情况下,以这种方式初始化r1,使其在执行*r1Adr.(**Rect) = *r2Adr.(**Rect)后正确更新,那将非常感激。

英文:

I have a lot of constraints in the issue I am encountering, so I have greatly simplified it to this unnatural code containing the following stuff:

  • A struct named Rect
  • rA and rB both of which point to a new Rect object
  • r1 and r2, which are interfaces containing rA and rB
  • r1Adr and r2Adr, which are interfaces containing the addresses of rA and rB

I want to do rA = rB without being allowed to reference rA or rB after declaring my variables.

(Note: you would think it would be easy, and that you would just do *r1.(*Rect) = *r2.(*Rect). However, the issue with this approach is that it does not point rA to rB's Rect object—it merely clones the values of rB's Rect to rA's Rect. So, I instead have to dereference a pointer to rA (r1Adr) and assign it to rB so that rA points to the same Rect object as rB.)

Below is my attempt at doing so:

type Rect struct {
	width int
}

func main() {
	rA := new(Rect)
	rB := new(Rect)

	var r1, r2, r1Adr, r2Adr any
	r1 = rA
	r2 = rB
	r1Adr = &rA
	r2Adr = &rB

	*r1Adr.(**Rect) = *r2Adr.(**Rect)

    // print the address of each Rect object being stored
	fmt.Printf("%p, %p, %p, %p, %p, %p", rA, rB, r1, r2, *r1Adr.(**Rect), *r2Adr.(**Rect))
}

0xc00001c038, 0xc00001c038, 0xc00001c030, 0xc00001c038, 0xc00001c038, 0xc00001c038

PLAYGROUND: https://go.dev/play/p/VnQwx6V7DNa

As you can see from the output, rA is correctly updating to rB, and r1Adr and r2Adr are reflecting this perfectly. However, r1's rA is not updating to rB, which we know because its output is different. Why is this? If rA is being updated to rB, and if r1 stores rA, then how is it that the rA pointed to by r1 is not updating to rB?

Any insight as to how I can initialize r1 in such a way (without changing it from an interface) that it properly updates after doing *r1Adr.(**Rect) = *r2Adr.(**Rect) would be greatly appreciated.

答案1

得分: 1

rArB是指向不同对象AB的两个指针。

r1是指向A的接口,r2是指向B的接口。

r1Addr是指向&rA的接口,r2Addr是指向&rB的接口。

因此,当你更新r1Addr的内容时,你将rA指向rB

然而,r1r2仍然指向AB,它们没有改变。

英文:

rA and rB are two pointers pointing to separate objects, A and B.

r1 is an interface pointing to A, and r2 is an interface pointing to B.

r1Addr is an interface pointing to &rA, and r2Addr is an interface pointing to &rB.

Thus, when you update the contents of r1Addr1, you point rA to rB.

However, r1 and r2 are still pointing to A and B; they did not change.

huangapple
  • 本文由 发表于 2022年10月17日 04:24:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/74090485.html
  • go
  • memory
  • memory-address
  • memory-management
  • pointers
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定