2009-11-27 9 views
1

Dans le code suivant, je crée un casse-tête puis je bouge dessus, ce qui ajoute un mouvement à son vecteur movesAlreadyDone. Ensuite, je crée un autre puzzle puis je bouge dessus, ce qui ajoute un mouvement à son vecteur movesAlreadyDone. Quand j'imprime les valeurs dans ce vecteur pour le second, il y a le mouvement du premier avec le mouvement du second. Quelqu'un peut-il me dire pourquoi il semble attribuer par référence et non la valeur? Les affectations vectorielles sont-elles copiées par valeur ou par référence dans la langue Go de Google?Les affectations vectorielles sont-elles copiées par valeur ou par référence dans la langue 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(); 
} 

Toute aide sera grandement appréciée. Merci!

Répondre

1

accessoire à la réponse, mais vector.New a été supprimé de versions récentes de Go. Vous devez écrire

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

Dans votre code d'origine, les éléments que vous copiez sont des pointeurs vers des vecteurs. C'est exactement la même chose que les pointeurs en C. Vous pouvez l'appeler "par référence" si vous voulez, mais ce sont des pointeurs.

Pour copier un vecteur entier, utilisez 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 
} 

Cela donne une copie unique, complète.

1

Dans votre code, movesAlreadyDone est un *vector.Vector; Lorsque vous affectez retVal.movesAlreadyDone = parent.movesAlreadyDone;, vous copiez une référence. Chaque fois qu'une modification vectorielle est effectuée sur retVal.movesAlreadyDone ou parent.movesAlreadyDone, vous modifiez le même vecteur sous-jacent.

Si vous souhaitez copier le contenu d'un vecteur dans un autre, vous devrez parcourir le vecteur source et pousser ses éléments vers le vecteur de destination. Comme si:

for n := range srcVect.Iter() { 
    dstVect.Push(n); 
} 
+2

Pas besoin de répéter - appelez simplement Vector.AppendVector. –