Go语言运行时如何根据指定import路径列出所有导入类型?
Go如何根据import路径列出指定包下的所有公开类型
问题原因
标准库go/importer的默认导入器仅支持读取GOROOT下的标准库包,以及GOPATH模式下预编译完成的第三方包,不兼容当前主流的Go Modules依赖管理模式,因此直接传入第三方module的子包路径会抛出找不到导入包的错误。
解决方案
推荐使用官方维护的golang.org/x/tools/go/packages库实现需求,该库原生支持Go Modules模式下的包解析,实现步骤如下:
- 先安装依赖包:
go get golang.org/x/tools/go/packages
- 示例代码如下:
package main import ( "fmt" "go/types" "golang.org/x/tools/go/packages" ) func main() { // 配置包加载模式,指定需要加载类型信息 cfg := &packages.Config{ Mode: packages.NeedName | packages.NeedTypes | packages.NeedTypesScope, } // 传入目标包的导入路径 pkgs, err := packages.Load(cfg, "github.com/aler9/goroslib/pkg/msgs/std_msgs") if err != nil { fmt.Printf("加载包失败: %v\n", err) return } for _, pkg := range pkgs { if len(pkg.Errors) > 0 { for _, e := range pkg.Errors { fmt.Printf("包解析错误: %v\n", e) } return } fmt.Printf("包 %s 下的公开类型:\n", pkg.PkgPath) scope := pkg.Types.Scope() for _, name := range scope.Names() { obj := scope.Lookup(name) // 仅输出公开的类型定义,如需输出常量、函数等可删除类型判断逻辑 if obj.Exported() { if _, ok := obj.(*types.TypeName); ok { fmt.Println(name) } } } } }
注意事项
- 运行代码前需要先在当前项目下执行
go get github.com/aler9/goroslib/pkg/msgs/std_msgs安装目标依赖,否则解析时会找不到对应包 - 如果需要列出包下所有公开元素(包含函数、变量、常量等),删除代码中
*types.TypeName的类型判断即可 - 如果一定要使用标准库
go/importer实现,需要切换到GOPATH模式:设置环境变量GO111MODULE=off,执行go get将依赖下载到$GOPATH/src目录下,再运行原有代码即可,但该方法适配性差,不推荐使用
内容的提问来源于stack exchange,提问作者Zheng Qu
相关产品推荐
相关产品推荐

