Как назначение в разделе post цикла Go for позволяет завершить этот цикл? - PullRequest
0 голосов
/ 08 февраля 2019

Я работаю над книгой "Язык программирования 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

1 Ответ

0 голосов
/ 08 февраля 2019

Когда c.NextSibling не ноль, кажется, что цикл завершается, так как значение цикла совпадает с предыдущей итерацией

Не уверен, что вы имели в виду, нода, вы неверно истолковываете что-то .Но петля for не виновата.Он, безусловно, не выходит из , в то время как его условие продолжения все еще выполняется.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...