Are vector assignments copied by value or by reference in Google's Go language?
Question
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!
Solution
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.
OTHER TIPS
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);
}