首页 > 解决方案 > 去变量结构重新分配错误?

问题描述

我试图了解这个小片段的行为,取自一个更大的单链表实现:

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

标签: go

解决方案


您使用数据“a”创建一个节点,并将该节点存储在一个变量 head 中,该变量不是指向节点的指针,而是一个节点。然后你做一些奇怪的事情来改变那个节点的数据,而不是别的:对链接的调用将首先得到你的节点 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)
}

推荐阅读