Вы на правильном пути, 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