我刚开始学习围棋。我有一个关于指针的问题。
在下面的代码中,代码中的以下行没有达到我的预期:
last_line.Next_line = &line // slice doesn't change
我希望切片也被更改,而不仅仅是局部变量last_line。
我做错了什么?
type Line struct {
Text string
Prev_line *Line
Next_line *Line
}
var (
lines []Line
last_line *Line
)
for i, record := range records {
var prev_line *Line = nil
text := record[0]
if i > 0 {
prev_line = &lines[i-1]
}
line := Line{
Text: text,
Prev_line: prev_line,
Next_line: nil}
if last_line != nil {
last_line.Next_line = &line // slice doesn't change
}
lines = append(lines, line)
last_line = &line
}
您的Line
类型是一个看起来相当标准的双链表。lines
变量包含这些对象的一部分。将这两者结合在一起有点不寻常——可以肯定的是,这并没有错,只是不寻常。而且,正如Matt Oestreich在评论中指出的那样,我们不太清楚records
中有什么(只是range
可以用于它,这样做之后,我们可以使用record[0]
来获得单个string
值(,所以可能有更好的方法来处理问题。
如果records
本身是一个切片或具有一个合理的len
,我们可以同时分配一个大小合适的Line
实例切片:
lines = make([]Line, len(records))
这是围棋场上的一个这样做的例子。
如果我们不能真正获得合适的len
——例如,如果records
是一个长度并不真正相关的信道——那么我们可能确实想要分配单独的线路,但在这种情况下,可能更明智的做法是首先避免将它们作为一个切片。单是双重链接的列表就足够了。
最后,如果您确实想要一个切片和这个双链接列表,请注意,使用append
可以将切片的元素复制到一个新的、更大的切片。如果这样做,则先前设置的任何元素中的指针都将指向旧的较小的切片。就语言本身而言,这并不是无效的——那些对象仍然存在,并且你的指针保持着它们;"活着"--但这可能根本不是你想要的。在这种情况下,在构建lines
切片之后,在最后设置所有指针更有意义,就像我提供的示例代码中一样。
(我写的样本故意有点奇怪,如果这是为了在家庭作业或考试中作弊,很可能会让你的家庭作业或测试成绩下降一点。:-(