Le assegnazioni vettoriali vengono copiate per valore o per riferimento nella lingua Go di Google?

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

  •  05-07-2019
  •  | 
  •  

Domanda

Nel codice seguente, creo un puzzle di pegging, quindi faccio una mossa su di esso che aggiunge una mossa al suo vettore MoveAlreadyDone. Quindi creo un altro puzzle di pegging, quindi eseguo una mossa su di esso che aggiunge una mossa ai suoi mosse Vettore già fatto. Quando stampo i valori in quel vettore per il secondo, contiene lo spostamento dal primo insieme allo spostamento dal secondo. Qualcuno può dirmi perché sembra assegnare per riferimento e non per valore? Le assegnazioni vettoriali vengono copiate per valore o per riferimento nella lingua Go di 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();
}

Qualsiasi aiuto sarà molto apprezzato. Grazie!

È stato utile?

Soluzione

Per inciso sulla risposta, ma vector.New è stato eliminato dalle versioni recenti di Go. Devi scrivere

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

Nel tuo codice originale, le cose che stai copiando sono puntatori a vettori. Questo è lo stesso dei puntatori in C. Puoi chiamarlo " per riferimento " se ti piace, ma sono puntatori.

Per copiare un intero vettore, utilizzare 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
}

Questo fornisce una copia unica completa.

Altri suggerimenti

Nel tuo codice, movesAlreadyDone è un * vector.Vector ; quando assegni retVal.movesAlreadyDone = parent.movesAlreadyDone; , stai copiando un riferimento. Ogni volta che viene effettuata una modifica del vettore su retVal.movesAlreadyDone o parent.movesAlreadyDone modificherai lo stesso vettore sottostante.

Se si desidera copiare il contenuto di un vettore su un altro, è necessario scorrere il vettore di origine e spingerne gli elementi sul vettore di destinazione. In questo modo:

for n := range srcVect.Iter() {
    dstVect.Push(n);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top