go - 使用 x/tools/go/packages 查找嵌入另一种类型的类型
问题描述
假设我有以下代码,
package w
import "log"
type Z struct {
log.Logger
}
type Y struct {} // skip this type
我想以编程方式查找类型Z
,由它嵌入的事实标识log.Logger
,如果不是,我想跳过声明,使用https://pkg.go.dev/golang.org/x/tools/go/packages
目前我已经能够编写以下代码,
package main
import (
"fmt"
"go/ast"
"go/token"
"os"
"path/filepath"
"golang.org/x/tools/go/packages"
)
func main() {
inputFile := os.Getenv("GOFILE")
cwd, err := os.Getwd()
if err != nil {
panic(err)
}
fmt.Println(inputFile)
fmt.Println(cwd)
cfg := &packages.Config{
// Mode: packages.NeedName | packages.NeedFiles | packages.NeedSyntax | packages.LoadTypes,
Mode: packages.NeedSyntax | packages.LoadTypes,
BuildFlags: []string{"-tags=sqlg"},
}
pkgs, err := packages.Load(cfg, cwd)
if err != nil {
fmt.Fprintf(os.Stderr, "load: %v\n", err)
os.Exit(1)
}
if packages.PrintErrors(pkgs) > 0 {
os.Exit(1)
}
for _, pkg := range pkgs {
fmt.Println(pkg.ID, pkg.GoFiles)
for _, s := range pkg.Syntax {
file := pkg.Fset.File(s.Pos())
if filepath.Base(file.Name()) != inputFile {
continue
}
for _, d := range s.Decls {
switch x := d.(type) {
case *ast.GenDecl:
if x.Tok == token.TYPE {
fmt.Printf("%#v\n", x.Specs)
}
case *ast.FuncDecl:
}
}
}
}
}
但我不太喜欢它,因为我正在挖掘语法树以查找 GenDecl,然后是 Specs 等
以前,使用包加载器https://godoc.org/golang.org/x/tools/go/loader
可以加载类型推断,搜索每个包的类型并检查接口兼容性;在我看来,我想要类似的东西。
鉴于它们简单地嵌入了特定类型,如何使用新的 packages 包来查找类型?
解决方案
包装内有一个Var.Embedded
。go/types
您可以使用 usegolang.org/x/tools/go/loader
来加载包并获取类型信息,然后使用Type.Underlying
and interface cast 来过滤掉结构类型,然后使用 iterate overStruct.Filed
来获取Var
字段,并检查Var
.
推荐阅读
- python - 写入文件:行数不匹配
- python - 导入 matplotlib.pyplot 时如何修复“对象没有属性”错误
- python - 使用带有解释的正则表达式获取所有日期格式
- flutter - 如何解决“容器切割另一个容器”问题
- c# - 异步方法同时调用 2 次
- java - 如何从中创建邻接矩阵?
- java - 我的简单 webview 应用程序现在在 googleplayconsole 上暂停,我该如何再次发布或删除它。?
- javascript - Openlayers 地图比例线相同的缩放率在公制中重复两次,即使缩放不同
- python-3.x - 更改发送到对话流代理的请求格式
- haskell - GHCi中的“return 1”如何显示“1”?