¿Las asignaciones de vectores se copian por valor o por referencia en el idioma Go de Google?

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

  •  05-07-2019
  •  | 
  •  

Pregunta

En el siguiente código, creo un rompecabezas de clavija y luego hago un movimiento en él que agrega un movimiento a su vector de movimientosAlreadyDone. Luego creo otro rompecabezas de clavijas y luego hago un movimiento en él que agrega un movimiento a su vector de movimientosAlreadyDone. Cuando imprimo los valores en ese vector para el segundo, tiene el movimiento desde el primero junto con el movimiento desde el segundo. ¿Alguien puede decirme por qué parece estar asignando por referencia y no por valor? ¿Las asignaciones de vectores se copian por valor o por referencia en el idioma Go de 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();
}

Cualquier ayuda será muy apreciada. Gracias!

¿Fue útil?

Solución

Incidental a la respuesta, pero vector.New se ha eliminado de las versiones recientes de Go. Necesitas escribir

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

En su código original, las cosas que está copiando son punteros a vectores. Esto es lo mismo que los punteros en C. Puede llamarlo " por referencia " Si quieres, pero son punteros.

Para copiar un vector completo, 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
}

Esto da una copia única completa.

Otros consejos

En su código, movesAlreadyDone es un * vector.Vector ; cuando asigna retVal.movesAlreadyDone = parent.movesAlreadyDone; , está copiando una referencia. Cada vez que se realice una modificación vectorial en retVal.movesAlreadyDone o parent.movesAlreadyDone , se modificará el mismo vector subyacente.

Si desea copiar el contenido de un vector a otro, deberá recorrer el vector de origen y enviar sus elementos al vector de destino. Al igual que:

for n := range srcVect.Iter() {
    dstVect.Push(n);
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top