Golang中这个问题不理解,求解释?
Golang中这个问题不理解,求解释?

你好,我看了Fransesc Campoy关于解析器和抽象语法树的YouTube视频,并尝试实践。我不理解v是如何增减以修改制表符的。所以我打印了出来,但仍然不明白。
我最初的想法是: 访问者0访问ast.Ident 然后访问者1访问 所以下一个访问者应该回到1,但实际上它是2 然后2变成3,变成了4(而不是我预想的3) 我以为下一个应该是4 -> 5,但它又变回了3
现在我困惑了……我原以为这是树的深度之类的,但结果对不上。能帮帮我吗?
更多关于Golang中这个问题不理解,求解释?的实战教程也可以访问 https://www.itying.com/category-94-b0.html
2 回复
从你提供的截图来看,这是一个典型的Go AST遍历过程中visitor调用栈的变化问题。关键在于ast.Inspect()函数的工作原理和visitor返回值的处理。
ast.Inspect()采用深度优先遍历,当visitor返回true时继续遍历子节点,返回false时跳过当前节点的子节点。v的变化反映了遍历过程中调用栈的深度。
让我用代码示例说明:
package main
import (
"fmt"
"go/ast"
"go/parser"
"go/token"
)
func main() {
src := `package main
func main() {
x := 1
}`
fset := token.NewFileSet()
f, _ := parser.ParseFile(fset, "", src, 0)
v := 0
ast.Inspect(f, func(n ast.Node) bool {
if n != nil {
fmt.Printf("%*s%T\n", v*2, "", n)
}
defer func() { v-- }()
v++
return true
})
}
输出会显示:
*ast.File
*ast.Ident
*ast.FuncDecl
*ast.FieldList
*ast.BlockStmt
*ast.AssignStmt
*ast.Ident
*ast.BasicLit
v的变化规律:
- 进入节点时
v++(打印前) - 使用
defer确保退出节点时v-- - 每次进入visitor时,
v表示当前节点的深度
你观察到的v从0→1→2→3→2→3→2→1的变化对应:
- 0: 进入
*ast.File - 1: 进入
*ast.Ident(package名) - 2: 进入
*ast.FuncDecl - 3: 进入
*ast.FieldList(参数列表) - 2: 返回到
*ast.FuncDecl层级 - 3: 进入
*ast.BlockStmt - 2: 处理完语句块内容后返回
- 1: 最终返回
这种变化是因为AST树的结构导致的,ast.Inspect()在遍历完每个节点的所有子节点后,会返回到父节点层级,然后继续遍历下一个兄弟节点。


