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 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料
  • ¥15 使用R语言marginaleffects包进行边际效应图绘制
  • ¥20 usb设备兼容性问题
  • ¥15 错误(10048): “调用exui内部功能”库命令的参数“参数4”不能接受空数据。怎么解决啊
  • ¥15 安装svn网络有问题怎么办