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,一切都是正确的。有人可以阐明这种意外行为吗?
解决方案
您使用数据“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)
}
推荐阅读
- angular - Azure 通信服务 - 断开连接后不更新视频设备
- ssh - mac 终端显示 myname@192 而不是 myname@myname-mac-pro
- typescript - 带有点符号的打字稿深度省略
- babylonjs - 使用 parcel.js 摇树 BabaylonJs
- javascript - 使用 redux 更新 React ApexCharts
- docker - web-api 无法连接到 Docker 作曲家网络中的 sqlserver
- amazon-web-services - 如何运行 AWS Cron 作业,它将运行一整周,但有一个例外(我不应该在上午 9 点到上午 9 点的周六运行)
- google-bigquery - Apache Beam - Bigquery 流式插入显示 RuntimeException:ManagedChannel 分配站点
- c# - 有没有办法将 Authorize 属性与没有身份验证标头的请求一起使用?
- android - Firebase 分析显示每日活跃用户异常