首页 > 解决方案 > 如何拥有不能用于具有不同名称空间的同一包的两个副本

问题描述

这是一篇博客文章的引述:

强制虚 URL go get 支持通过一个 URL 获取包

不同于包的 repo 的 URL。这些 URL 称为虚 URL,要求您提供带有 Go 工具识别的特定元标记的页面。您可以使用虚 URL 提供具有自定义域和路径的包。

例如,

$ go get cloud.google.com/go/datastore

在后台从https://code.googlesource.com/gocloud查看源代码 ,并将其放在 $GOPATH/src/cloud.google.com/go/datastore 下的工作区中。

鉴于 code.googlesource.com/gocloud 已经在提供此包,是否可以从该 URL 获取包?如果您强制使用虚 URL,答案是否定的。

为此,请在包中添加导入语句。go 工具将拒绝从任何其他路径导入此包,并向用户显示友好错误。如果您不强制使用您的虚 URL,则由于命名空间不同,您的包的两个副本将无法一起工作。

package datastore // import "cloud.google.com/go/datastore"

有人可以解释最后一行是什么意思吗?

如果您不强制使用您的虚 URL,则由于命名空间不同,您的包的两个副本将无法一起工作。

或者在一个例子中展示它?

标签: go

解决方案


这很简单。

如果您的软件包托管在 ,github.com/foo/bar并且您有虚 URL foo.com/bar,那么有人可以同时执行以下操作:

import "github.com/foo/bar"

import "foo.com/bar"

如果您有不同的文件或包以不同的路径导入相同的包,这将是有问题的。

想象一下这两个文件在同一个包中:

// foo.go
package foo

import "github.com/foo/bar"

func frobnicate(x *bar.Something) { /* ... */ }
// bar.go
package foo

import "foo.com/bar"

func widget() {
    x := *bar.Something{}
    frobnicate(x) // compilation error: cannot use x (type foo.com/bar.Something) as type github.com/foo/bar.Something
}

推荐阅读