如何在运行时发现所有包类型?

2024-01-07

据我所知(参见here https://stackoverflow.com/a/22188310/605022, and here https://stackoverflow.com/a/20805018/605022)中没有类型发现机制反射包 http://golang.org/pkg/reflect/,它期望您已经拥有要检查的类型或值的实例。

有没有other如何在正在运行的 go 包中发现所有导出类型(尤其是结构)?

这是我希望拥有的(但它不存在):

import "time"
import "fmt"

func main() {
    var types []reflect.Type
    types = reflect.DiscoverTypes(time)
    fmt.Println(types)
}

最终目标是能够发现包中满足特定条件的所有结构,然后能够实例化这些结构的新实例。

顺便说一句,识别类型的注册函数是not对我的用例来说是有效的方法。


无论您是否认为这是一个好主意,这就是我想要这种功能的原因(因为我知道您会问):

我写了一个代码生成实用程序 https://github.com/smartystreets/gunit加载 go 源文件并构建 AST 来扫描嵌入指定类型的类型。该实用程序的输出是一组基于发现的类型的 go 测试函数。我使用调用此实用程序go generate创建测试函数然后运行go test执行生成的测试函数。每次测试更改(或添加新类型)时,我必须在重新运行之前重新运行 gogeneratego test。这就是为什么注册功能不是一个有效的选项。我想避免go generate步骤,但这需要我的实用程序成为由正在运行的包导入的库。库代码需要以某种方式扫描正在运行的命名空间init()对于嵌入预期库类型的类型。


在Go 1.5中,你可以使用新的包types http://golang.org/pkg/go/types/ and importer http://golang.org/pkg/go/importer/检查二进制文件和源代码包。例如:

package main

import (
    "fmt"
    "go/importer"
)

func main() {
    pkg, err := importer.Default().Import("time")
    if err != nil {
        fmt.Printf("error: %s\n", err.Error())
        return
    }
    for _, declName := range pkg.Scope().Names() {
        fmt.Println(declName)
    }
}

您可以使用该包go/build http://golang.org/pkg/go/build/提取所有已安装的软件包。或者您可以配置Lookup http://golang.org/pkg/go/importer/#Lookup进口商检查环境之外的二进制文件。

1.5之前,唯一简单的方法是使用该包ast http://golang.org/pkg/go/ast/编译源代码。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在运行时发现所有包类型? 的相关文章

随机推荐