如何解析方法声明?

我正在尝试解析方法声明。基本上我需要获取接收器基本类型 ( type hello) 和返回类型 ( notypeand error)的语法节点。这个ast包看起来很简单,但由于某种原因我没有得到我需要的数据(即字段报告为零)。


唯一有用的数据似乎只在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)

            }

        }

    }

}



三国纷争
浏览 167回答 1
1回答

拉丁的传说

要获得类型,您需要查看Type可能是 anast.StarExpr或 an的属性ast.Ident。在这里看看这个:package mainimport (    "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 typetype hello string// type notype is not that cooltype 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)            }        }    }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go