loops - 我的迭代函数有什么问题

标签 loops pointers go linked-list

我正在尝试遍历一个简单的链表。这应该很简单,但它不起作用。迭代函数包含问题。

package main

import (
    "fmt"
    "time"
)

type Node struct {
    Next  *Node
    Value int
}

func main() {
    //Load up 100 *Node in a linked list (albeit a simple one)
    head := &Node{Value: 0}
    current := head
    for i := 1; i < 100; i++ {
        current.Next = &Node{Value: i}
        current = current.Next
        fmt.Printf("current %p %+v\n", current, current)
    }

    iterate(head)
}

//Iterate through the list starting at head. It never 
//advances past the first "Next", loops forever.
func iterate(head *Node) {
    for n := head.Next; n != nil; head = n {
        fmt.Printf("head %+v n %+v\n", head, n)
        time.Sleep(time.Second * 1)
    }
}

iterate 的输出类似于:

head &{Next:0x20818c230 Value:0} n &{Next:0x20818c280 Value:1}
head &{Next:0x20818c280 Value:1} n &{Next:0x20818c280 Value:1}
head &{Next:0x20818c280 Value:1} n &{Next:0x20818c280 Value:1}
head &{Next:0x20818c280 Value:1} n &{Next:0x20818c280 Value:1}
head &{Next:0x20818c280 Value:1} n &{Next:0x20818c280 Value:1}

为了好玩,我尝试了另一个版本的迭代循环,它使用一个函数来获取 .Next。我的想法是也许 head.Next 由于某种循环优化总是指向我原来的头。该理论似乎不正确。

func iterate(head *Node) {
    getNext := func (n *Node) *Node {
        return n.Next
    }

    for n := getNext(head); n != nil; head = n {
        fmt.Printf("head %+v n %+v\n", head, n)
        time.Sleep(time.Second * 1)
    }
}

天哪,我只是没看到吗?我在循环体执行后将 head 设置为 n,它等于下一个节点。下一个 head.Next 不应该返回后续的 Node 直到我们到达一个 nil 节点并退出循环吗?

---更新---

我提出了以下迭代修改,它现在更加清晰并且实际上是正确的:

func iterate(head *Node) {
    for ; head != nil; head = head.Next {
        fmt.Printf("head %+v head.Next %+v\n", head, head.Next)
    }
}

最佳答案

查看 For statement spec :

  • 循环的“init 语句”部分 (n := head.Next) 仅计算一次。
  • post 语句不断将head 重置为n 的初始值(getNext(head))。

因此无限循环。

n := getNext(head) 放在循环中应该会更好,如 working example :

for n := head; n != nil; head = n {
    fmt.Printf("head %+v n %+v\n", head, n)
    time.Sleep(time.Second * 1)
    n = head.Next
}

关于loops - 我的迭代函数有什么问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28759275/

相关文章:

C++在访问持有该成员的对象时无法访问对象成员

c++ - 为什么在 QSharedPointer 中使用窗口时会发生段错误?

go - GO Lang Web应用程序-自动编译和重新加载

go - 更新全局变量的成员未反射(reflect)在全局变量中

javascript - 为什么使用 "for...in"进行数组迭代是一个坏主意?

python - Pandas - 迭代行并比较以前的值 - 更快

r - R 中 if-else 中的逻辑运算符

javascript - 在 JavaScript 中使用 json 填充数据库

c - memcpy - 从不同大小的整数转换为指针

go - PowerPC 版本的 Go