【问题标题】:Updating value in pointer reciever method but value not updating在指针接收器方法中更新值但值未更新
【发布时间】:2020-02-01 08:29:59
【问题描述】:

我正在 Go 中实现一个链表。我写了一个在链表开头插入节点的方法:

func (n *node) insertAtBegining(d int){
    nn := &node{d,n}
    n = nn
}

作为指针接收器的方法应该更新节点n,但它没有这样做。

例如,

head.printList()
head.insertAtBegining(30)
head.printList()

返回

42 -> 56 -> 89 -> nil
42 -> 56 -> 89 -> nil

你可以在https://play.golang.org/p/rpI6lbAywOQ看到完整的实现。

我做错了什么?

【问题讨论】:

标签: pointers go linked-list


【解决方案1】:

问题的根源在于调用head.insertAtBegining(30)不会改变head的值(它仍然指向node{42, nil})。

您已经假设insertAtBegining 中的n = nn 将更新head,但事实并非如此。我认为insertAtBegining 是标准函数而不是method 更容易理解:

insertAtBegining(head, 30)
...
func insertAtBegining(n *node, d int) *node{
    nn := &node{d,n}
    n = nn
}

由于 Go 通过值传递所有参数(您可以传递一个指针,但它作为一个值传递)我认为这不会改变 head 很明显(如果你想这样做,你需要定义函数func insertAtBegining(n **node, d int) *node{ 并通过 &head.

你的方法也有同样的问题。

最简单的解决方法是将insertAtBegining 重新定义为 (playground):

func (n *node) insertAtBegining(d int) *node{
    nn := &node{d,n}
    return nn
}

它现在返回新的头部,因此您可以像这样使用它:head = head.insertAtBegining(30)

另一种方法是将列表管理封装在一个结构中;这是list.List 中采用的方法。这样做的好处是用户不需要了解列表是如何存储的。

【讨论】:

    猜你喜欢
    • 2022-09-22
    • 2019-09-22
    • 2021-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-02
    相关资源
    最近更新 更多