围绕这个问题有很多问题,包括为什么你不应该使用import "./my/path"
以及为什么它只能起作用,因为一些遗留的代码需要它。
如果这是正确的,你如何处理项目的封装和扩展github分叉?在其他任何语言中,我可以执行项目的github分支,或者git clone,并且所有内容都封装在那里。如何从go项目中获得相同的行为?
使用go“hello world”示例的简单示例。
hello.go
package main
import ("fmt"
"github.com/golang/examples/stringutil")
func main() {
fmt.Printf(stringutil.Reverse("hello, world")+"\n")
}
以上作品很棒。但是如果我想在子目录中使用我自己的stringutil并将编译为单个二进制文件,那么仍然需要完整的路径:
package main
import ("fmt"
"github.com/myrepo/examples/util/stringutil")
func main() {
fmt.Printf(stringutil.Reverse("hello, world")+"\n")
}
现在,如果有人复制或分发我的回购,它直接依赖于“github.com/myrepo/”,,即使这完全是在内部使用的!
如果有20个不同的文件导入utils/
怎么办?每次有人分叉时我需要更换每一个吗?这是一个无关紧要的变化和无意义的git提交。
我在这里缺少什么?为什么相对路径这么糟糕?如何在不更改数十个文件的情况下分叉引用其自己的子目录(及其包)的项目?
答案 0 :(得分:3)
至于不允许相对导入的原因,您可以从一些角度阅读本讨论:https://groups.google.com/forum/#!msg/golang-nuts/n9d8RzVnadk/07f9RDlwLsYJ
就我个人而言,至少对内部导入而言,我更愿意启用它们。正是因为你所描述的原因。
现在,如何应对这种情况?
如果你的fork只是另一个项目的一个小修复,可能很快就会被接受为PR - 只需手动编辑git遥控器就可以引用你自己的git repo而不是原来的。如果您正在使用像godep这样的销售解决方案,它将顺利运行,因为保存它只会提供您的分叉代码,go get
永远不会直接使用。
如果您的fork是一个很大的变化,并且您打算保持分叉,请重写所有导入路径。您可以使用sed
自动执行此操作,也可以使用支持重写正在格式化的代码的gofmt -r
。
[编辑]我还发现了这个旨在帮助解决这种情况的工具:https://github.com/rogpeppe/govers
我已经完成了1和2 - 当我刚刚对某个库进行了一个小错误修复时,我只是更改了遥控器并进行了审核。当我实际分叉库而无意将我的更改合并回来时,我更改了所有导入路径并继续仅使用我的仓库。
我还可以考虑增加销售工具,允许自动化这些东西,但我认为它们中的任何一个都不支持它。