我用Go弄脏了手,虽然我理解并欣赏Go所建立的简单的原则,但我想了解背后的理由。在依赖项提取工具-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"didSelectRowAtIndexPath Row %ld",(long)indexPath.row);
}
和go get
语句中使用内置包版本控制方法。
如果我理解正确,import
和go get
会从import
获取包,但他们无法引用分支或标记。虽然有像gopkg.in这样的工具可以绕过这个限制,但官方的工具链是:
说实话,事情并不那么容易,因为软件包版本控制需要一种策略来处理冲突的传递依赖关系,例如: HEAD
取决于X
和A
,每个B
取决于C
的不同版本。
来自Java背景,似乎这种限制带来了一些风险和问题,其中包括:
产品/包装的演变和第三方公共API的破坏是不可避免的,因此版本控制必须是工具链恕我直言中的一等公民。
Git-repo-per-version 政策效率极低:
企业采用可能受阻,开发团队可能会回避语言,因为:
HEAD
意味着他们无法控制或冻结他们的第三方代表,从而导致潜在的无法预测的最终产品。HEAD
进行测试(并非世界上每家公司都是谷歌)。虽然我确实理解后一种风险可以 - 并且必须 - 通过持续集成来缓解,但它并不能解决问题的根本原因。
我错过了哪些信息?在人力资源有限的企业中部署Go时,如何处理包上游变更?
答案 0 :(得分:7)
由vendoring解决,它是Go 1.5的一部分作为实验性功能,如果go命令在其环境中以GO15VENDOREXPERIMENT=1
运行,则可以启用它,并且将是“完整的” “Go 1.6中的功能。另请参阅Vendor Directories。
可以找到导致Go 1.5 Vedor实验的原始讨论here。
vendoring的本质是您创建一个名为vendor
的文件夹,并放置代码所依赖的软件包的确切版本。 vendor
文件夹中的代码只能由源自vendor
父目录树的目录树中的代码导入,您可以使用导入路径从vendor
导入包,就好像{{1将是vendor
文件夹(即,使用导出路径省略前缀并包括供应商元素)。
示例:
workspace/src
在此示例中,/home/user/goworkspace/
src/
mymath/
mymath.go
vendor/
github.com/somebob/math
math.go
是github.com/somebob/math
包(来自mymath
)使用的外部包。如果导入如下,则可以从mymath.go
使用它:
mymath.go
(而不是import "github.com/somebob/math"
哪个不好。)
答案 1 :(得分:1)
虽然Go没有标准软件包管理器,但有足够的选项可以使构建重现(即使在人力有限的企业中)。
供应,在@icza的另一个答案中描述。这几乎完全等同于在Java中检入版本化的jar文件。在maven变得流行之前,这是使用ant构建工具的非常常见的方法。实际上,销售要好得多,因为你不能丢失源代码。
这是第一个选项的轻微变化。您可以通过检查预定义的依赖项版本,在构建期间填充供应商文件夹,而不是检查已售出的源代码。有自动完成此过程的工具(例如滑行)。
最后,您可以在内部存储库中维护所有第3方库的预定义版本,并将其添加到GOPATH。 https://blog.gopheracademy.com/advent-2015/go-in-a-monorepo/
请注意,不兼容的传递依赖项并非特定于Go。它们也存在于Java(以及大多数其他语言)中,尽管Java有一种通过使程序更复杂来部分解决这个问题的机制 - 类加载器。请注意,Go将在编译时报告所有不兼容性,而在Java中,某些不兼容性仅在运行时触发(因为后期链接)。
Java工具链没有版本概念。它由外部工具提供 - maven。我相信,当Go变得更加成熟和流行时,将会出现类似的标准依赖管理工具。