Копируются ли векторные назначения по значению или по ссылке на языке Google Go?
Вопрос
В следующем коде я создаю одну головоломку-колышек, а затем делаю на ней ход, который добавляет ход к его воду MoveAlreadyDone. Затем я создаю еще одну головоломку-колышек, затем делаю ход, добавляя движение к его воду MoveAlreadyDone. Когда я распечатываю значения в этом векторе для второго, в нем есть движение от первого и движение от второго. Может кто-нибудь сказать мне, почему он, кажется, присваивает ссылки, а не значение? Копируются ли векторные назначения по значению или по ссылке на языке Go Google?
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();
}
Любая помощь будет принята с благодарностью. Спасибо!
Решение
Случайный ответ, но vector.New
был удален из последних версий Go. Вам нужно написать
func (p *PegPuzzle) InitPegPuzzle(){
p.movesAlreadyDone = new (vector.Vector);
}
В исходном коде копируемые объекты являются указателями на векторы. Это так же, как указатели на 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
}
Другие советы
В вашем коде moveAlreadyDone
является * vector.Vector
; когда вы назначаете retVal.movesAlreadyDone = parent.movesAlreadyDone;
, вы копируете ссылку. Каждый раз, когда модификация вектора выполняется либо в retVal.movesAlreadyDone
, либо в parent.movesAlreadyDone
, вы будете изменять тот же базовый вектор.
Если вы хотите скопировать содержимое одного вектора в другой, вам нужно будет выполнить итерацию по исходному вектору и перенести его элементы в целевой вектор. Вот так:
for n := range srcVect.Iter() {
dstVect.Push(n);
}