指针操作不会更改其在切片中的引用

  • 本文关键字:切片 引用 操作 指针 go
  • 更新时间 :
  • 英文 :


我刚开始学习围棋。我有一个关于指针的问题。

在下面的代码中,代码中的以下行没有达到我的预期:

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切片之后,在最后设置所有指针更有意义,就像我提供的示例代码中一样。

(我写的样本故意有点奇怪,如果这是为了在家庭作业或考试中作弊,很可能会让你的家庭作业或测试成绩下降一点。:-(

最新更新