dongtao1262 2018-05-25 08:18
浏览 33
已采纳

Go lang func参数类型

I am trying to find func parameter type and its name to generate some code. I am using ast package for it. I've found parameter name, but I can't find parameter type name.

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条回答 默认 最新

  • dongzi5062 2018-05-25 09:04
    关注

    You're on the right track, FuncType.Params is the (incoming) parameter list of the function. Its List field holds all the parameters, which are of type 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
    }
    

    The Field.Type holds the type of the parameter which is an interface type ast.Expr with simply embeds the ast.Node which only provides you the start and end position of the type in the source. Basically this should be enough to get the text representation of the type.

    Let's see a simple example. We will analyze this function:

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

    And the code to print its parameters, including type names:

    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:
    ", fd.Name)
            for _, param := range fd.Type.Params.List {
                fmt.Printf("  Name: %s
    ", param.Names[0])
                fmt.Printf("    ast type          : %T
    ", param.Type)
                fmt.Printf("    type desc         : %+v
    ", param.Type)
                fmt.Printf("    type name from src: %s
    ",
                    src[param.Type.Pos()-offset:param.Type.End()-offset])
            }
        }
        return true
    })
    

    Output (try it on the 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
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 phython如何实现以下功能?查找同一用户名的消费金额合并—
  • ¥15 孟德尔随机化怎样画共定位分析图
  • ¥18 模拟电路问题解答有偿速度
  • ¥15 CST仿真别人的模型结果仿真结果S参数完全不对
  • ¥15 误删注册表文件致win10无法开启
  • ¥15 请问在阿里云服务器中怎么利用数据库制作网站
  • ¥60 ESP32怎么烧录自启动程序
  • ¥50 html2canvas超出滚动条不显示
  • ¥15 java业务性能问题求解(sql,业务设计相关)
  • ¥15 52810 尾椎c三个a 写蓝牙地址