2 回答
TA贡献1946条经验 获得超3个赞
多亏了叶子bebop的答案,我能够写一个更短的程序,原始帖子没有显示,但在v1中,我有8个级别的缩进来查找结构的嵌入属性。
这受到 https://pkg.go.dev/golang.org/x/tools@v0.0.0-20201226215659-b1c90890d22a/go/packages/gopackages 提供的演示的启发
package main
import (
"fmt"
"go/types"
"os"
"strings"
"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,
}
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 {
// qual := types.RelativeTo(pkg.Types)
scope := pkg.Types.Scope()
for _, name := range scope.Names() {
obj := scope.Lookup(name)
if obj != nil && obj.Type() != nil && obj.Type().Underlying() != nil {
// obj is types.Named,
// obj.Type() is types.TypeName
// obj.Type().Underlying() exposes the types.Struct which
// gives access to the desired types.Var.Embedded()
st, ok := obj.Type().Underlying().(*types.Struct)
if !ok {
continue
}
for i := 0; i < st.NumFields(); i++ {
f := st.Field(i)
if f.Embedded() && strings.HasSuffix(f.Type().String(), "log.Logger") {
fmt.Printf("%#v\n", f)
}
}
}
}
}
}
我相信它存在一个使用访问者模式的较短版本,但我还没有找到它。
在这个版本中,我仍然依靠字符串比较来类型检查属性,这是以后使用类型推断可以改进的东西。
- 2 回答
- 0 关注
- 142 浏览
添加回答
举报