英文:
Are vector assignments copied by value or by reference in Google's Go language?
问题
在以下代码中,我创建了一个木板拼图,然后对其进行了一次移动,将移动添加到其movesAlreadyDone向量中。然后我创建了另一个木板拼图,然后对其进行了一次移动,将移动添加到其movesAlreadyDone向量中。当我打印出第二个木板拼图中该向量的值时,它包含了第一个木板拼图中的移动以及第二个木板拼图中的移动。有人能告诉我为什么它似乎是通过引用而不是值进行赋值的吗?在Google的Go语言中,向量赋值是按值还是按引用进行的?
package main
import "fmt"
import "container/vector"
type Move struct { x0, y0, x1, y1 int }
type PegPuzzle struct {
movesAlreadyDone *vector.Vector;
}
func (p *PegPuzzle) InitPegPuzzle(){
p.movesAlreadyDone = vector.New(0);
}
func NewChildPegPuzzle(parent *PegPuzzle) *PegPuzzle{
retVal := new(PegPuzzle);
retVal.movesAlreadyDone = parent.movesAlreadyDone;
return retVal
}
func (p *PegPuzzle) doMove(move Move){
p.movesAlreadyDone.Push(move);
}
func (p *PegPuzzle) printPuzzleInfo(){
fmt.Printf("-----------START----------------------\n");
fmt.Printf("moves already done: %v\n", p.movesAlreadyDone);
fmt.Printf("------------END-----------------------\n");
}
func main() {
p := new(PegPuzzle);
cp1 := new(PegPuzzle);
cp2 := new(PegPuzzle);
p.InitPegPuzzle();
cp1 = NewChildPegPuzzle(p);
cp1.doMove(Move{1,1,2,3});
cp1.printPuzzleInfo();
cp2 = NewChildPegPuzzle(p);
cp2.doMove(Move{3,2,5,1});
cp2.printPuzzleInfo();
}
非常感谢任何帮助!谢谢!
英文:
In the following code, I create one peg puzzle then do a move on it which adds a move to its movesAlreadyDone vector. Then I create another peg puzzle then do a move on it which adds a move to its movesAlreadyDone vector. When I print out the values in that vector for the second one, it has the move in it from the first one along with the move from the second one. Can anyone tell me why it seems to be assigning by reference and not value? Are vector assignments copied by value or by reference in Google's Go language?
package main
import "fmt"
import "container/vector"
type Move struct { x0, y0, x1, y1 int }
type PegPuzzle struct {
movesAlreadyDone * vector.Vector;
}
func (p *PegPuzzle) InitPegPuzzle(){
p.movesAlreadyDone = vector.New(0);
}
func NewChildPegPuzzle(parent *PegPuzzle) *PegPuzzle{
retVal := new(PegPuzzle);
retVal.movesAlreadyDone = parent.movesAlreadyDone;
return retVal
}
func (p *PegPuzzle) doMove(move Move){
p.movesAlreadyDone.Push(move);
}
func (p *PegPuzzle) printPuzzleInfo(){
fmt.Printf("-----------START----------------------\n");
fmt.Printf("moves already done: %v\n", p.movesAlreadyDone);
fmt.Printf("------------END-----------------------\n");
}
func main() {
p := new(PegPuzzle);
cp1 := new(PegPuzzle);
cp2 := new(PegPuzzle);
p.InitPegPuzzle();
cp1 = NewChildPegPuzzle(p);
cp1.doMove(Move{1,1,2,3});
cp1.printPuzzleInfo();
cp2 = NewChildPegPuzzle(p);
cp2.doMove(Move{3,2,5,1});
cp2.printPuzzleInfo();
}
Any help will be greatly appreciated. Thanks!
答案1
得分: 1
在你的代码中,movesAlreadyDone
是一个 *vector.Vector
;当你赋值 retVal.movesAlreadyDone = parent.movesAlreadyDone;
时,你是在复制一个引用。无论是在 retVal.movesAlreadyDone
还是 parent.movesAlreadyDone
上进行向量修改,你都会修改同一个底层向量。
如果你想将一个向量的内容复制到另一个向量中,你需要遍历源向量,并将其元素推入目标向量。像这样:
for n := range srcVect.Iter() {
dstVect.Push(n);
}
英文:
In your code, movesAlreadyDone
is a *vector.Vector
; when you assign retVal.movesAlreadyDone = parent.movesAlreadyDone;
, you are copying a reference. Anytime a vector modification is done on either retVal.movesAlreadyDone
or parent.movesAlreadyDone
you'll be modifying the same underlying vector.
If you want to copy the contents of one vector to another you will need to iterate through the source vector and push its elements to the destination vector. Like so:
for n := range srcVect.Iter() {
dstVect.Push(n);
}
答案2
得分: 1
在你的原始代码中,你正在复制的是指向向量的指针。这与C语言中的指针是一样的。你可以称之为“按引用传递”,但它们实际上是指针。
要复制整个向量,请使用InsertVector
:
func (p *PegPuzzle) InitPegPuzzle(){
p.movesAlreadyDone = new(vector.Vector)
}
func NewChildPegPuzzle(parent *PegPuzzle) *PegPuzzle{
retVal := new(PegPuzzle)
retVal.InitPegPuzzle()
retVal.movesAlreadyDone.InsertVector(0, parent.movesAlreadyDone)
return retVal
}
这将得到一个完整的唯一副本。
英文:
Incidental to the answer, but vector.New
has been deleted from recent versions of Go. You need to write
func (p *PegPuzzle) InitPegPuzzle(){
p.movesAlreadyDone = new (vector.Vector);
}
In your original code, the things you are copying are pointers to vectors. This is just the same as pointers in C. You can call it "by reference" if you like, but they're pointers.
To copy an entire vector, use InsertVector
:
func (p *PegPuzzle) InitPegPuzzle(){
p.movesAlreadyDone = new (vector.Vector);
}
func NewChildPegPuzzle(parent *PegPuzzle) *PegPuzzle{
retVal := new (PegPuzzle);
retVal.InitPegPuzzle ();
retVal.movesAlreadyDone.InsertVector (0, parent.movesAlreadyDone);
return retVal
}
This gives a complete unique copy.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论