我正在尝试解析方法声明。基本上,我需要获取接收方基本类型(type hello)和返回类型(notype和error)的语法节点。该ast程序包看起来很简单,但是由于某种原因,我没有获得所需的数据(即,字段为nil)。
type hello
notype
error
ast
唯一有用的数据似乎仅在Object -> Decl类型为字段的字段中提供,interface{} 因此我认为我无法序列化它。
Object -> Decl
interface{}
任何帮助,将不胜感激。代码如下:
package main import ( "fmt" "go/ast" "go/parser" "go/token" ) func main() { // src is the input for which we want to inspect the AST. src := ` package mypack // type hello is a cool type type hello string // type notype is not that cool type notype int // func printme is like nothing else. func (x *hello)printme(s string)(notype, error){ return 0, nil } ` // Create the AST by parsing src. fset := token.NewFileSet() // positions are relative to fset f, err := parser.ParseFile(fset, "src.go", src, 0) if err != nil { panic(err) } // Inspect the AST and find our function var mf ast.FuncDecl ast.Inspect(f, func(n ast.Node) bool { switch x := n.(type) { case *ast.FuncDecl: mf = *x } return true }) if mf.Recv != nil { fmt.Printf("\n receivers:") for _, v := range mf.Recv.List { fmt.Printf(",tag %v", v.Tag) for _, xv := range v.Names { fmt.Printf("name %v, decl %v, data %v, type %v", xv.Name, xv.Obj.Decl, xv.Obj.Data, xv.Obj.Type) } } } }
操场
要获取类型,您需要查看Type可能是an ast.StarExpr或an 的属性ast.Ident。
Type
ast.StarExpr
ast.Ident
这里看看这个:
package main import ( "fmt" "go/ast" "go/parser" "go/token" ) func main() { // src is the input for which we want to inspect the AST. src := ` package mypack // type hello is a cool type type hello string // type notype is not that cool type notype int // printme is like nothing else. func (x *hello)printme(s string)(notype, error){ return 0, nil } ` // Create the AST by parsing src. fset := token.NewFileSet() // positions are relative to fset f, err := parser.ParseFile(fset, "src.go", src, 0) if err != nil { panic(err) } // Inspect the AST and find our function var mf ast.FuncDecl ast.Inspect(f, func(n ast.Node) bool { switch x := n.(type) { case *ast.FuncDecl: mf = *x } return true }) if mf.Recv != nil { for _, v := range mf.Recv.List { fmt.Print("recv type : ") switch xv := v.Type.(type) { case *ast.StarExpr: if si, ok := xv.X.(*ast.Ident); ok { fmt.Println(si.Name) } case *ast.Ident: fmt.Println(xv.Name) } } } }