Копируются ли векторные назначения по значению или по ссылке на языке Google Go? - PullRequest
1 голос
/ 27 ноября 2009

В следующем коде я создаю одну головоломку-колышек, затем делаю ход, добавляя движение к вектору 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();
}

Любая помощь будет принята с благодарностью. Спасибо!

Ответы [ 2 ]

1 голос
/ 27 ноября 2009

Не относится к ответу, но 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
}

Это дает полную уникальную копию.

1 голос
/ 27 ноября 2009

В вашем коде movesAlreadyDone - это *vector.Vector; когда вы назначаете retVal.movesAlreadyDone = parent.movesAlreadyDone;, вы копируете ссылку. Каждый раз, когда модификация вектора выполняется на retVal.movesAlreadyDone или parent.movesAlreadyDone, вы будете изменять тот же базовый вектор.

Если вы хотите скопировать содержимое одного вектора в другой, вам нужно будет выполнить итерацию по исходному вектору и перенести его элементы в целевой вектор. Вот так:

for n := range srcVect.Iter() {
    dstVect.Push(n);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...