São atribuições vetor copiado por valor ou por referência na linguagem Go do Google?

StackOverflow https://stackoverflow.com/questions/1806673

  •  05-07-2019
  •  | 
  •  

Pergunta

No código a seguir, eu criar um quebra-cabeça peg em seguida, fazer uma jogada sobre ele, que acrescenta um movimento para seu vetor movesAlreadyDone. Então eu criar um outro quebra-cabeça peg em seguida, fazer uma jogada sobre ele, que acrescenta um movimento para seu vetor movesAlreadyDone. Quando imprimir os valores em que o vector para a segunda, que possui o movimento em que a partir do primeiro, juntamente com o movimento da segunda. Alguém pode me dizer por que parece ser a atribuição por referência e não valor? São atribuições vetor copiado por valor ou por referência na linguagem Go do 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();
}

Qualquer ajuda será muito apreciada. Obrigado!

Foi útil?

Solução

fundo para a resposta, mas vector.New foi excluído versões recentes do Go. Você precisa escrever

func (p *PegPuzzle) InitPegPuzzle(){
    p.movesAlreadyDone = new (vector.Vector);
}

Em seu código original, as coisas que você está copiando são ponteiros para vetores. Este é exatamente o mesmo como ponteiros em C. Você pode chamá-lo "por referência" se quiser, mas eles são ponteiros.

Para copiar um vetor inteiro, 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
}

Isto dá uma única cópia completa.

Outras dicas

Em seu código, movesAlreadyDone é um *vector.Vector; quando você atribui retVal.movesAlreadyDone = parent.movesAlreadyDone;, você está copiando uma referência. Sempre que uma modificação vector é feito em ambos retVal.movesAlreadyDone ou parent.movesAlreadyDone você estará modificando o mesmo vector subjacente.

Se você quiser copiar o conteúdo de um vetor para outro que você vai precisar para percorrer o vetor de origem e empurrar seus elementos ao vetor de destino. Como assim:

for n := range srcVect.Iter() {
    dstVect.Push(n);
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top