Go lang func参数类型

时间:2018-05-25 08:18:08

标签: go abstract-syntax-tree

我正在尝试查找func参数类型及其名称以生成一些代码。 我正在使用ast包。 我找到了参数名称,但我找不到参数类型名称。

for _, fun := range findFunc(node) { //ast.FuncDecl

    if  fun.Recv != nil {
        for _, field := range fun.Type.Params.List {
            for _, name := range field.Names {
                println(name.Name)  //Func field name
                //How to find field type name here?
            }

        }
    }

}

1 个答案:

答案 0 :(得分:1)

您处于正确的轨道上,FuncType.Params是该功能的(传入)参数列表。其List字段包含所有参数,类型为ast.Field

type Field struct {
        Doc     *CommentGroup // associated documentation; or nil
        Names   []*Ident      // field/method/parameter names; or nil if anonymous field
        Type    Expr          // field/method/parameter type
        Tag     *BasicLit     // field tag; or nil
        Comment *CommentGroup // line comments; or nil
}

Field.Type保存参数的类型,它是一个接口类型ast.Expr,只需嵌入ast.Node,它只提供源中类型的起始和结束位置。基本上这应该足以获得该类型的文本表示。

让我们看一个简单的例子。我们将分析这个功能:

func myfunc(i int, s string, err error, pt image.Point, x []float64) {}

打印参数的代码,包括类型名称:

src := `package xx
func myfunc(i int, s string, err error, pt image.Point, x []float64) {}`

fset := token.NewFileSet()
f, err := parser.ParseFile(fset, "src.go", src, 0)
if err != nil {
    panic(err)
}
offset := f.Pos()

ast.Inspect(f, func(n ast.Node) bool {
    if fd, ok := n.(*ast.FuncDecl); ok {
        fmt.Printf("Function: %s, parameters:\n", fd.Name)
        for _, param := range fd.Type.Params.List {
            fmt.Printf("  Name: %s\n", param.Names[0])
            fmt.Printf("    ast type          : %T\n", param.Type)
            fmt.Printf("    type desc         : %+v\n", param.Type)
            fmt.Printf("    type name from src: %s\n",
                src[param.Type.Pos()-offset:param.Type.End()-offset])
        }
    }
    return true
})

输出(在Go Playground上尝试):

Function: myfunc, parameters:
  Name: i
    ast type          : *ast.Ident
    type desc         : int
    type name from src: int
  Name: s
    ast type          : *ast.Ident
    type desc         : string
    type name from src: string
  Name: err
    ast type          : *ast.Ident
    type desc         : error
    type name from src: error
  Name: pt
    ast type          : *ast.SelectorExpr
    type desc         : &{X:image Sel:Point}
    type name from src: image.Point
  Name: x
    ast type          : *ast.ArrayType
    type desc         : &{Lbrack:71 Len:<nil> Elt:float64}
    type name from src: []float64