[英]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 中的变量n
被append
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
}
但总的来说,这仍然不是一个好策略:例如,当给定nil
值n
时,此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.