2009-11-27 104 views
1

在下面的代码中,我创建了一个挂钩谜题,然后在它上面做一个移动,将其添加到其movesAlreadyDone向量中。然后,我创建另一个钉谜题,然后在它上面移动,这增加了一个移动到它的移动已完成的向量。当我打印出第二个向量中的值时,它从第一个向前移动,并从第二个向上移动。谁能告诉我为什么它似乎是通过引用分配而不是价值? Google的Go语言是按照价值还是参考来复制矢量分配?Google的Go语言是通过值还是引用来复制矢量分配?

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(); 
} 

任何帮助将不胜感激。谢谢!

回答

1

附带的答案,但vector.New已从近期版本的Go中删除。您需要编写

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

在您的原始代码中,您正在复制的内容是指向向量的指针。这与C中的指针相同。如果你喜欢,可以称其为“通过引用”,但它们是指针。

要复制整个载体,应用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 
} 

这给出了一个完整的独特的副本。

1

在您的代码中,movesAlreadyDone*vector.Vector;当您分配retVal.movesAlreadyDone = parent.movesAlreadyDone;时,您正在复制参考。随时在retVal.movesAlreadyDoneparent.movesAlreadyDone上完成矢量修改,您将修改相同的基础矢量。

如果要将一个矢量的内容复制到另一个矢量,则需要遍历源矢量并将其元素推送到目标矢量。像这样:

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

无需迭代 - 只需调用Vector.AppendVector。 – 2009-11-27 08:56:17