zoukankan      html  css  js  c++  java
  • go ast解析出函数参数名

    做了一个gin的扩展,想把请求参数里的内容自动传到方法参数里,需要用到反射,但是反射有个缺点是无法拿到参数名(注意:不是函数名)
    做的以下测试。

    测试代码如下

    package main
    
    import (
    	"go/ast"
    	"go/parser"
    	"go/token"
    	"log"
    )
    
    func main() {
    	src := []byte(`
    package test
    import "fmt"
    func sayHello(msg string) {
    	fmt.Println("helloworld" + msg)
    }`)
    	fset := token.NewFileSet()
    	file, err := parser.ParseFile(fset, "", src, 0)
    	if err != nil {
    		log.Fatal(err)
    	}
    	ast.Print(fset, file)
    }
    

    以下是ast解析内容,注意第42行函数sayHello的参数名msg已经可以拿到了

         0  *ast.File {
         1  .  Package: 2:1
         2  .  Name: *ast.Ident {
         3  .  .  NamePos: 2:9
         4  .  .  Name: "test"
         5  .  }
         6  .  Decls: []ast.Decl (len = 2) {
         7  .  .  0: *ast.GenDecl {
         8  .  .  .  TokPos: 3:1
         9  .  .  .  Tok: import
        10  .  .  .  Lparen: -
        11  .  .  .  Specs: []ast.Spec (len = 1) {
        12  .  .  .  .  0: *ast.ImportSpec {
        13  .  .  .  .  .  Path: *ast.BasicLit {
        14  .  .  .  .  .  .  ValuePos: 3:8
        15  .  .  .  .  .  .  Kind: STRING
        16  .  .  .  .  .  .  Value: ""fmt""
        17  .  .  .  .  .  }
        18  .  .  .  .  .  EndPos: -
        19  .  .  .  .  }
        20  .  .  .  }
        21  .  .  .  Rparen: -
        22  .  .  }
        23  .  .  1: *ast.FuncDecl {
        24  .  .  .  Name: *ast.Ident {
        25  .  .  .  .  NamePos: 4:6
        26  .  .  .  .  Name: "sayHello"
        27  .  .  .  .  Obj: *ast.Object {
        28  .  .  .  .  .  Kind: func
        29  .  .  .  .  .  Name: "sayHello"
        30  .  .  .  .  .  Decl: *(obj @ 23)
        31  .  .  .  .  }
        32  .  .  .  }
        33  .  .  .  Type: *ast.FuncType {
        34  .  .  .  .  Func: 4:1
        35  .  .  .  .  Params: *ast.FieldList {
        36  .  .  .  .  .  Opening: 4:14
        37  .  .  .  .  .  List: []*ast.Field (len = 1) {
        38  .  .  .  .  .  .  0: *ast.Field {
        39  .  .  .  .  .  .  .  Names: []*ast.Ident (len = 1) {
        40  .  .  .  .  .  .  .  .  0: *ast.Ident {
        41  .  .  .  .  .  .  .  .  .  NamePos: 4:15
        42  .  .  .  .  .  .  .  .  .  Name: "msg"
        43  .  .  .  .  .  .  .  .  .  Obj: *ast.Object {
        44  .  .  .  .  .  .  .  .  .  .  Kind: var
        45  .  .  .  .  .  .  .  .  .  .  Name: "msg"
        46  .  .  .  .  .  .  .  .  .  .  Decl: *(obj @ 38)
        47  .  .  .  .  .  .  .  .  .  }
        48  .  .  .  .  .  .  .  .  }
        49  .  .  .  .  .  .  .  }
        50  .  .  .  .  .  .  .  Type: *ast.Ident {
        51  .  .  .  .  .  .  .  .  NamePos: 4:19
        52  .  .  .  .  .  .  .  .  Name: "string"
        53  .  .  .  .  .  .  .  }
        54  .  .  .  .  .  .  }
        55  .  .  .  .  .  }
        56  .  .  .  .  .  Closing: 4:25
        57  .  .  .  .  }
        58  .  .  .  }
        59  .  .  .  Body: *ast.BlockStmt {
        60  .  .  .  .  Lbrace: 4:27
        61  .  .  .  .  List: []ast.Stmt (len = 1) {
        62  .  .  .  .  .  0: *ast.ExprStmt {
        63  .  .  .  .  .  .  X: *ast.CallExpr {
        64  .  .  .  .  .  .  .  Fun: *ast.SelectorExpr {
        65  .  .  .  .  .  .  .  .  X: *ast.Ident {
        66  .  .  .  .  .  .  .  .  .  NamePos: 5:2
        67  .  .  .  .  .  .  .  .  .  Name: "fmt"
        68  .  .  .  .  .  .  .  .  }
        69  .  .  .  .  .  .  .  .  Sel: *ast.Ident {
        70  .  .  .  .  .  .  .  .  .  NamePos: 5:6
        71  .  .  .  .  .  .  .  .  .  Name: "Println"
        72  .  .  .  .  .  .  .  .  }
        73  .  .  .  .  .  .  .  }
        74  .  .  .  .  .  .  .  Lparen: 5:13
        75  .  .  .  .  .  .  .  Args: []ast.Expr (len = 1) {
        76  .  .  .  .  .  .  .  .  0: *ast.BinaryExpr {
        77  .  .  .  .  .  .  .  .  .  X: *ast.BasicLit {
        78  .  .  .  .  .  .  .  .  .  .  ValuePos: 5:14
        79  .  .  .  .  .  .  .  .  .  .  Kind: STRING
        80  .  .  .  .  .  .  .  .  .  .  Value: ""helloworld""
        81  .  .  .  .  .  .  .  .  .  }
        82  .  .  .  .  .  .  .  .  .  OpPos: 5:27
        83  .  .  .  .  .  .  .  .  .  Op: +
        84  .  .  .  .  .  .  .  .  .  Y: *ast.Ident {
        85  .  .  .  .  .  .  .  .  .  .  NamePos: 5:29
        86  .  .  .  .  .  .  .  .  .  .  Name: "msg"
        87  .  .  .  .  .  .  .  .  .  .  Obj: *(obj @ 43)
        88  .  .  .  .  .  .  .  .  .  }
        89  .  .  .  .  .  .  .  .  }
        90  .  .  .  .  .  .  .  }
        91  .  .  .  .  .  .  .  Ellipsis: -
        92  .  .  .  .  .  .  .  Rparen: 5:32
        93  .  .  .  .  .  .  }
        94  .  .  .  .  .  }
        95  .  .  .  .  }
        96  .  .  .  .  Rbrace: 6:1
        97  .  .  .  }
        98  .  .  }
        99  .  }
       100  .  Scope: *ast.Scope {
       101  .  .  Objects: map[string]*ast.Object (len = 1) {
       102  .  .  .  "sayHello": *(obj @ 27)
       103  .  .  }
       104  .  }
       105  .  Imports: []*ast.ImportSpec (len = 1) {
       106  .  .  0: *(obj @ 12)
       107  .  }
       108  .  Unresolved: []*ast.Ident (len = 2) {
       109  .  .  0: *(obj @ 50)
       110  .  .  1: *(obj @ 65)
       111  .  }
       112  }
    
    
  • 相关阅读:
    [Next] 六.next的优化
    [Next] 五.next自定义内容
    Mac解决端口占用
    [Next] 四.在next中引入redux
    [Next] 服务端渲染知识补充
    [Next] 三.next自定义服务器和路由
    哪些使用UDP、TCP、IP协议
    IDEA配置git
    ssm整合配置
    git传输远程仓库
  • 原文地址:https://www.cnblogs.com/nickchou/p/15420515.html
Copyright © 2011-2022 走看看