我正在尝试从较大的单链列表实现中了解这个小片段的行为:
package main
import "fmt"
type Node struct {
Next *Node
Data string
}
func (n *Node) Link(data string) Node {
link := Node{Data: data, Next: n}
return link
}
func main() {
head := Node{Data: "a"}
head = head.Link("b")
fmt.Printf("head = %+v\n", head)
fmt.Printf("head.Next = %+v\n", head.Next)
}
输出:
head = {Next:0xc42000a060 Data:b}
head.Next = &{Next:0xc42000a060 Data:b}
为什么head.Next链接到自身而不是“ a”节点?这与变量名称“ head”的重新分配有关,因为如果您更改行:
head = head.Link("b")
到
head2 := head.Link("b")
和printf head2,一切正确。有人可以阐明这种意外行为吗?
答案 0 :(得分:3)
您使用数据“ a”创建一个节点,并将该节点存储在变量头中,该变量头不是指针,而是指向节点的指针。然后,您做了一些奇怪的事情来更改该节点的数据,而没有其他操作:对链接的调用将首先获取您的Node a的地址(以调用指针方法)。然后,创建一个新的Node值,其Next指向Node a。您返回该节点(而不是指向它的指针)。然后,您用新内容(即数据和下一步)覆盖节点头中的所有内容。
使用指针遍历:
func (n *Node) Link(data string) *Node { return &Node{Data: data, Next: n} }
func main() {
head := &Node{Data: "a"}
fmt.Printf("head = %+v\n", *head)
head = head.Link("b")
fmt.Printf("head = %+v\n", *head)
fmt.Printf("head.Next = %+v\n", *head.Next)
}