在Go for循环的post部分中进行分配如何使此循环退出?

时间:2019-02-08 08:46:16

标签: go

我正在研究“ Go编程语言”这本书,并在第5章中了解了循环语法的不寻常之处。我已经精简了以下示例,但是整个程序是on the book's GitHub page

type Node struct {
    int                     NodeType
    FirstChild, NextSibling *Node
}

func visit(n *Node) {
  for c:= n.FirstChild; c != nil; c = c.NextSibling {
    visit(c)
  }
}

我脑海中的C解析器告诉我c.NextSibling将始终指向Node或为nil。在这种情况下,循环应该总是中断或永远继续。

c.NextSibling不是nil时,似乎循环正在退出,因为循环值与上一次迭代相同,但是我在Go Language Specification中找不到任何内容支持。

我已经编译了该程序,并确认它可以按照书中的内容工作。

我错过了一些基本知识还是在这里发生其他事情了?


完整示例,带有工具代码(感谢Sergio):

package main

import (
    "fmt"
)

type Node struct {
    NodeId                  int
    FirstChild, NextSibling *Node
}

func visit(n *Node) {
    fmt.Printf("Entering node %d\n", n.NodeId)
    for c := n.FirstChild; c != nil; c = nextSib(c) {
        fmt.Printf("Will now visit node %d\n", c.NodeId)
        visit(c)
    }
}

func nextSib(n *Node) *Node {
    next := n.NextSibling
    fmt.Printf("In nextSib for %d %t\n", n.NodeId, next != nil)
    return next
}

func main() {
    c4 := &Node{NodeId: 5}
    c3 := &Node{NodeId: 4}
    c2 := &Node{NodeId: 3, NextSibling: c3}
    c1 := &Node{NodeId: 2, FirstChild: c4, NextSibling: c2}
    root := &Node{NodeId: 1, FirstChild: c1}

    visit(root)
}

输出:

Entering node 1
Will now visit node 2
Entering node 2
Will now visit node 5
Entering node 5
In nextSib for 5 false
In nextSib for 2 true
Will now visit node 3
Entering node 3
In nextSib for 3 true
Will now visit node 4
Entering node 4
In nextSib for 4 false

1 个答案:

答案 0 :(得分:2)

  

c.NextSibling不为nil时,似乎循环正在退出,因为循环值与上一次迭代相同

不知道您的意思是什么,但是是的,您误解了某事。但是,for循环不应该受到指责。可以肯定,does not exit的继续条件仍然成立。

type Node struct {
    NodeId                  int
    FirstChild, NextSibling *Node
}

func visit(n *Node) {
    for c := n.FirstChild; c != nil; c = c.NextSibling {
        fmt.Printf("seeing node %d\n", c.NodeId)
        visit(c)
    }
}

func main() {
    c3 := &Node{NodeId: 4}
    c2 := &Node{NodeId: 3, NextSibling: c3}
    c1 := &Node{NodeId: 2, NextSibling: c2}
    root := &Node{NodeId: 1, FirstChild: c1}

    visit(root)
}

输出

seeing node 2
seeing node 3
seeing node 4