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

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


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

当我修改追加方法时,我得到了预期的结果,但没有返回任何内容。


千巷猫影
浏览 76回答 3
3回答

手掌心

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}

小唯快跑啊

这个功能:func (n *Node) append(val int) (*Node){      for n.next != nil {     n = n.next      }      n.next = newNode(val)     return n}一般不返回其原始参数。它返回(假设非空)列表中倒数第二个节点。因此:n = n.append(4)添加一个节点holding4到原始节点holding 3,然后返回原始节点holding 3,但是:n = n.append(5)将持有 的节点添加5到原始列表,但随后返回指向持有 的节点的指针4。这就是你4,5,现在看到的原因。出于同样的原因,后续调用会不断重复最后两个元素。您可以修改您的append函数以保存原始返回值并返回该值: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}但总的来说,这仍然不是一个很好的策略:例如,当给定-valued时,这append不起作用。考虑构建一个能够处理此类情况的列表类型。或者,正如Hsaio 的回答一样,您可以让调用者直接挂在头节点上。如果你这样做,你可以让函数返回尾指针:nilnappendfunc (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()List(标准 Go 包中已经有一个container/list实现,它可以很好地为您完成这些工作。您可以创建一个整体列表容器实例,而不是直接指向列表中的每个元素,该实例允许您在前面插入, insert-at-back、remove-from-anywhere 等等。这有点尴尬,因为它用于interface{}数据,因此需要类型断言来获取每个节点的值。)

回首忆惘然

n函数中的变量main被函数n中的变量覆盖append。
打开App,查看更多内容
随时随地看视频慕课网APP