英文:
abstract syntax tree (AST) scan
问题
我正在尝试从Go AST中提取函数调用:
$ cat main.go
package main
import ("fmt"; "go/ast"; "go/token"; "go/parser"; "io/ioutil")
func CalledFuncs(n ast.Node) bool {
switch n.(type) {
case *ast.CallExpr:
l := ast.CallExpr(n).Lparen
r := ast.CallExpr(n).Right
fmt.Printf("call %d( ... %d)\n",l,r)
}
return true
}
func main() {
fset := token.NewFileSet()
src,_ := ioutil.ReadFile("simple.go")
f, _ := parser.ParseFile(fset,">>",src,0)
ast.Inspect(f, CalledFuncs)
}
但是Go编译器报错,说我不能进行类型转换:
$ go build -o main main.go
# command-line-arguments
./main.go:7:26: cannot convert n (type ast.Node) to type ast.CallExpr
./main.go:8:26: cannot convert n (type ast.Node) to type ast.CallExpr
我可能漏掉了什么。
英文:
I'm trying to extract function calls from go AST:
$ cat main.go
package main
import ("fmt"; "go/ast"; "go/token"; "go/parser"; "io/ioutil")
func CalledFuncs(n ast.Node) bool {
switch n.(type) {
case *ast.CallExpr:
l := ast.CallExpr(n).Lparen
r := ast.CallExpr(n).Right
fmt.Printf("call %d( ... %d)\n",l,r)
}
return true
}
func main() {
fset := token.NewFileSet()
src,_ := ioutil.ReadFile("simple.go")
f, _ := parser.ParseFile(fset,">>",src,0)
ast.Inspect(f, CalledFuncs)
}
But the go compiler complains I can't do the casting:
$ go build -o main main.go
# command-line-arguments
./main.go:7:26: cannot convert n (type ast.Node) to type ast.CallExpr
./main.go:8:26: cannot convert n (type ast.Node) to type ast.CallExpr
I'm probably missing something here.
答案1
得分: 1
https://golang.org/ref/spec#Type_switches
TypeSwitchGuard
可以包含短变量声明。当使用该形式时,变量在每个子句的隐式块的末尾声明。在仅列出一个类型的子句中,变量具有该类型;否则,变量具有TypeSwitchGuard
中表达式的类型。
这意味着你可以这样做:
func CalledFuncs(n ast.Node) bool {
switch x := n.(type) {
case *ast.CallExpr:
l := x.Lparen
r := x.Rparen
fmt.Printf("call %d( ... %d)\n", l, r)
}
return true
}
英文:
https://golang.org/ref/spec#Type_switches
> The TypeSwitchGuard
may include a short variable declaration. When
> that form is used, the variable is declared at the end of the
> TypeSwitchCase
in the implicit block of each clause. In clauses with a
> case listing exactly one type, the variable has that type; otherwise,
> the variable has the type of the expression in the TypeSwitchGuard
.
That means that you can do the following:
func CalledFuncs(n ast.Node) bool {
switch x := n.(type) {
case *ast.CallExpr:
l := x.Lparen
r := x.Rparen
fmt.Printf("call %d( ... %d)\n", l, r)
}
return true
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论