首页 > 解决方案 > 如何以编程方式检索声明给定类型的包路径?

问题描述

我正在寻找一种方法来检索本地安装的包,其中包含给定类型的声明和默认包名称。

IE:

// FindPackagesForType returns the list of possible packages for a given type
func FindPackagesForType(typeName string) []string {
    return []string {} // TODO: implement
}

func TestFindPackagesForType(t *testing.T) {
    assert.Contains(t, FindPackagesForType("io.Reader"), "io")
    assert.Contains(
        t,
        FindPackagesForType("types.Timestamp"),
        "github.com/gogo/protobuf/types",
    )
    assert.Contains(
        t,
        FindPackagesForType("types.ContainerCreateConfig"),
        "github.com/docker/docker/api/types",
    )
}

我可以尝试检索所有已安装的包,并在每个查找声明时通过 AST,但如果有一个解决方案可以更有效地做到这一点,同时还提供对 go 模块的支持,我想使用它。

这样做的原因是为了改进代码生成工具。这个想法是让用户提供类型的名称,并让工具识别最有可能的候选者,就像 goimports 添加缺失的导入一样。

标签: goabstract-syntax-treegofmtgoimports

解决方案


您可以使用reflect.TypeOf(any).PkgPath()获取特定类型的包路径。但是,我们需要传递具有所需类型的对象(而不是您想要的字符串)。

package main

import (
    "bytes"
    "fmt"
    "reflect"
    "gopkg.in/mgo.v2/bson"
)

func main() {
    var a bytes.Buffer
    fmt.Println(FindPackagesForType(a)) // output: bytes

    var b bson.M
    fmt.Println(FindPackagesForType(b)) // output: gopkg.in/mgo.v2/bson
}

func FindPackagesForType(any interface{}) string {
    return reflect.TypeOf(any).PkgPath()
}

推荐阅读