登录
首页 >  Golang >  Go问答

如何在 AST 解析器中将类型解析为原语

来源:stackoverflow

时间:2024-04-24 20:18:32 390浏览 收藏

积累知识,胜过积蓄金银!毕竟在Golang开发的过程中,会遇到各种各样的问题,往往都是一些细节知识点还没有掌握好而导致的,因此基础知识点的积累是很重要的。下面本文《如何在 AST 解析器中将类型解析为原语》,就带大家讲解一下知识点,若是你对本文感兴趣,或者是想搞懂其中某个知识点,就请你继续往下看吧~

问题内容

我想提取函数的签名,以便能够在它们上生成一些包装方法。为此,我正在使用 golang.org/x/tools/go/packages 这为我提供了阅读 ast 的可能性。

例如,对于函数 func myfunc(param int) 定义,您会收到一些

ast.funcdecl{
    type: *fieldlist{
        list: []*field{
            {
                names: []*ident{ /*...*/ },
                type:  nil, /*...*/
            },
        },
    },
}

其中 type 代表类型。

我想为所有 int 参数生成一些特殊代码,但 int 也可以通过某种类型声明隐藏

type MyType int

如何将 ast 类型转换为编译器拥有的真实类型?


正确答案


packages.NeedTypespackages.NeedTypesInfo 添加到加载模式。这样,每个加载的包都会初始化其 TypesInfo 字段,并且该字段的类型 *types.Info 有一个名为 Types 的字段,它将 ast 表达式映射到类型。您可以通过以下方式使用它:

func main() {
    loadConfig := new(packages.Config)
    loadConfig.Mode = packages.NeedSyntax | packages.NeedTypes | packages.NeedTypesInfo
    loadConfig.Fset = token.NewFileSet()
    pkgs, err := packages.Load(loadConfig, "syscall")
    if err != nil {
        panic(err)
    }

    for _, pkg := range pkgs {
        for _, syn := range pkg.Syntax {
            for _, dec := range syn.Decls {
                if fd, ok := dec.(*ast.FuncDecl); ok && fd.Name.Name == "Kill" {
                    x1 := fd.Type.Params.List[0].Type // int
                    x2 := fd.Type.Params.List[1].Type // syscall.Signal

                    tv1 := pkg.TypesInfo.Types[x1]
                    tv2 := pkg.TypesInfo.Types[x2]

                    if basic, ok := tv1.Type.(*types.Basic); ok {
                        fmt.Printf("%#v\n", basic) // int
                    }

                    if named, ok := tv2.Type.(*types.Named); ok {
                        fmt.Printf("%v\n", named.Obj())         // *types.TypeName (Signal)
                        fmt.Printf("%#v\n", named.Underlying()) // *types.Basic (int)
                    }
                }
            }
        }
    }
}

以上就是《如何在 AST 解析器中将类型解析为原语》的详细内容,更多关于的资料请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>