Я работаю над книгой "Язык программирования Go" и в 5-й главе узнал, что является необычным для синтаксиса цикла. Я сократил приведенный ниже пример, но вся программа на этой книге .Страница GitHub .
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 , чтобы подтвердить это.
Я скомпилировал эту программу и подтвердил, что она работает согласно книге.
Я что-то упустил или что-то еще здесь происходит?
Полный пример с инструментированным кодом (спасибо Серхио):
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