繁体   English   中英

go 方法 - 指针接收器并返回相同的指针

[英]go method - pointer receiver and returning same pointer

结构上的 go 方法接收指针引用,进行一些修改并返回相同的指针。 该结构具有相同结构的嵌套引用:当使用值调用 append 方法时,由于某种原因它丢失了先前的值。

package main

import (
    "fmt"
)
type Node struct{
    next *Node
    val int
}
func newNode(val int) (*Node){
    n := Node{
    val: val,
    }
   return &n
}
func (n *Node) append(val int) (*Node){
      for n.next != nil {
     n = n.next
      }
      n.next = newNode(val)
     return n
}

func (n *Node)printList(){
    for n != nil {
         fmt.Printf("%d,", n.val)
         n = n.next
    }
    fmt.Println()
}


func main() {
   n := newNode(3)
   n.printList()
   n = n.append(4)
   n.printList()
   n = n.append(5)
   n.printList()
   n = n.append(6)
   n.printList()    
}
output:
3,
3,4,
4,5,
5,6,

我期待 3,4,5,6,- 可能是我在这里完全错过了一些基础知识。 如果您有一些意见,将不胜感激。

https://play.golang.org/p/-zDH98UNFLa

当我修改 append 方法不返回任何内容时,我得到了预期的结果。

append()返回下一个节点的指针。 因此printList()只打印从下一个节点开始的节点。 如果你想打印列表中的所有节点,你应该添加一个变量来存储引用到这个列表的起始节点的指针。

func main() {
    n := newNode(3)

    head := n
    head.printList()

    n = n.append(4)
    head.printList()

    n = n.append(5)
    head.printList()

    n = n.append(6)
    head.printList() // 3,4,5,6
}

main function 中的变量nappend function 中的n覆盖。

这个 function:

func (n *Node) append(val int) (*Node){
      for n.next != nil {
     n = n.next
      }
      n.next = newNode(val)
     return n
}

一般返回其原始参数。 它返回(假定为非空)列表中的倒数第二个节点。 因此:

n = n.append(4)

将持有4的节点添加到持有3的原始节点,然后返回持有3的原始节点,但是:

n = n.append(5)

将持有5的节点添加到原始列表中,但随后返回指向持有4的节点的指针。 这就是为什么此时您会看到4,5, 出于同样的原因,后续调用会不断重复最后两个元素。

您可以修改您的append function 以保存原始返回值并返回

func (n *Node) append(val int) *Node {
    // find current tail
    t := n
    for t.next != nil {
        t = t.next
    }
    t.next = newNode(val)
    return n
}

但总的来说,这仍然不是一个好策略:例如,当给定niln时,此append不起作用。 考虑构建一个处理这种情况的列表类型。 或者,就像在Hsaio 的回答中一样,您可以让调用者直接挂在头节点上。 如果你这样做,你可以让append function 返回尾指针:

func (n *Node) append(val int) *Node {
    n.next = newNode(val)
    return n.next
}

然后像这样使用它:

head := newNode(3)
t := append(head, 4)
t = append(t, 5)
t = append(t, 6)
head.printList()

(标准 Go 包container/list中已经有一个List实现,它可以很好地为您完成这些工作。您无需直接指向列表中的每个元素,而是创建一个整体列表容器实例,它允许您插入 - at-front、insert-at-back、remove-from-anywhere 等等。有点尴尬的是它使用interface{}作为数据,所以它需要一个类型断言来获取每个节点的值。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM