Werden Vektorbelegungen von Wert kopiert oder durch Bezugnahme in Googles Go Sprache?
Frage
Im folgenden Code, erstelle ich einen Stift Puzzle tun dann einen Zug auf sie, die einen Umzug in seine movesAlreadyDone Vektor hinzufügt. Dann erstelle ich einen anderen peg Puzzle dann einen Schritt auf sie zu tun, die einen Umzug in seine movesAlreadyDone Vektor hinzufügt. Wenn ich die Werte für die zweite in diesem Vektor auszudrucken, hat es die Bewegung in sie von der ersten zusammen mit der Bewegung von der zweiten. Kann mir jemand sagen, warum es unter Bezugnahme auf wird die Zuordnung scheint und nicht zu schätzen? Vektorbelegungen von Wert oder als Referenz kopiert werden in Googles Go Sprache?
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();
}
Jede Hilfe wird sehr geschätzt. Dank!
Lösung
im Hintergrund auf die Antwort, aber vector.New
wurde von neueren Versionen von Go gelöscht. Sie müssen schreiben
func (p *PegPuzzle) InitPegPuzzle(){
p.movesAlreadyDone = new (vector.Vector);
}
In Ihrem ursprünglichen Code, die Dinge, die Sie kopieren sind Zeiger auf Vektoren. Dies ist genau die gleiche wie Zeiger in C. Sie es nennen können „by reference“, wenn Sie mögen, aber sie sind Zeiger.
Um einen ganzen Vektor zu kopieren, verwenden Sie 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
}
Dies ergibt eine vollständige eindeutige Kopie.
Andere Tipps
Sie in Ihrem Code ist movesAlreadyDone
ein *vector.Vector
; wenn Sie retVal.movesAlreadyDone = parent.movesAlreadyDone;
zuweisen, kopieren Sie einen Verweis. Jedesmal, wenn eine Vektor-Modifikation wird auf beiden retVal.movesAlreadyDone
getan oder parent.movesAlreadyDone
Sie werden den gleichen zugrunde liegenden Vektor werden zu ändern.
Wenn Sie den Inhalt eines Vektors in ein anderes kopieren möchten, müssen Sie über den Quellenvektor iterieren und seine Elemente in den Zielvektor drücken. Wie so:
for n := range srcVect.Iter() {
dstVect.Push(n);
}