去变量结构重新分配错误?

时间:2018-07-02 06:37:15

标签: go

我正在尝试从较大的单链列表实现中了解这个小片段的行为:

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,一切正确。有人可以阐明这种意外行为吗?

1 个答案:

答案 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)
}