代码之家  ›  专栏  ›  技术社区  ›  Ross MacArthur

如何检索类型。对象。类型

  •  0
  • Ross MacArthur  · 技术社区  · 3 年前

    我正在使用 golang.org/x/tools/go/packages 加载Go包并检查结构。我想知道 packages.Package 从中导入结构字段。

    func load() (any, error) {
        pkg, err := loadPackage(".")
        if err != nil {
            return nil, err
        }
    
        st, err := loadStruct(pkg, "myStruct")
        if err != nil {
            return nil, err
        }
    
        for i := 0; i < st.NumFields(); i++ {
            field := st.Field(i)
    
            // Let's say this field is like `amount decimal.Decimal` how can I get
            // a reference to the decimal package as a packages.Package
            // FIXME
        }
    
        return nil, nil
    }
    
    func loadPackage(name string) (*packages.Package, error) {
        pkgs, err := packages.Load(
            &packages.Config{
                Mode: packages.NeedName | packages.NeedImports | packages.NeedDeps |
                    packages.NeedTypes | packages.NeedTypesInfo | packages.NeedSyntax}, ".")
        if err != nil {
            log.WithError(err).Fatal("failed to load package")
        }
        if len(pkgs) != 1 {
            return nil, fmt.Errorf("expected 1 package, got %d", len(pkgs))
        }
        return pkgs[0], nil
    }
    
    func loadStruct(pkg *packages.Package, name string) (*types.Struct, error) {
        obj := pkg.Types.Scope().Lookup(name)
        if obj == nil {
            return nil, fmt.Errorf("could not find struct %s", name)
        }
        st, ok := obj.Type().Underlying().(*types.Struct)
        if !ok {
            return nil, fmt.Errorf("%s is not a struct", name)
        }
        return st, nil
    }
    
    
    0 回复  |  直到 3 年前