有人可以解释为什么GOPATH方便以及它应该如何使用?

Nik*_*Nik 34 go

我是Go编程语言的新手,每个教程都从将GOPATH设置为当前项目文件夹开始.

我错过了什么吗?程序员真的应该在他cd到他的新Go项目文件夹时手动设置GOPATH 吗?我已经阅读了几篇关于GOPATH的常见问题条目,但仍无法绕过它.

为什么GOROOT存在呢?它的目的是什么?

是否有任何自动工具可以检测当前目录是否是Go项目的根文件夹(例如,通过某些隐藏文件)并自动将GOPATH更改为此目录?

谢谢,任何建议真的很赞赏

PS.例如,如果他们生活在单一的"工作空间"环境中,我会开发完全脱节的Go项目A,B和C. 我猜不是,但是我应该怎么做GOPATH和GOROOT呢?

Elw*_*nar 30

目标GOPATH是将所有包集中到一个公共工作区.它本身并不是一个新概念(例如,考虑Java Classpath),但是由于不支持包版本控制,Go的使用非常简单.

Go程序员不应该GOPATH在输入新项目文件夹时手动设置.每个项目文件夹本身应该是一个包,并且位于GOPATH其他包中,因此GOPATH应该只设置一次.教程首先进行设置GOPATH,以便将教程工作区与其他任何东西隔开(或者只是假设用户尚未设置GOPATH).

GOROOT设置为Go程序员提供标准包,你不需要对它做任何事情.简而言之,有一条规则GOROOT:永远不要触摸它.不要在其中安装任何东西,不要修改标准包等.

我不知道在当前目录中检测Go项目的工具,但创建起来不应该非常复杂.

您如何处理不同的项目取决于您.Go方法是将每个项目作为包放在$GOPATH/src目录中,并从那里做所有事情.因为我不喜欢它,所以我GOPATH将自己定义为$HOME/.go.然后我将每个项目放在其他地方(我的计算机中的任何位置)的专用目录中,并将项目目录符号链接到我的$GOPATH/src目录中.然后我可以使用每个Go工具链命令(例如go build myproject),将项目用作另一个的包,等等.

  • @dig,这在[Go nuts邮件列表](http://groups.google.com/d/forum/golang-nuts)上通常称为"vendoring".[有很多第三方工具可以执行此操作](https://code.google.com/p/go-wiki/wiki/PackageManagementTools),以及[`gopkg.in`](http:/ /gopkg.in)服务是从另一个角度解决问题的替代解决方案.请务必阅读[this](http://nathany.com/go-packages/)和[this](http://dave.cheney.net/2013/10/10/why-i-think-go-包管理是重要的)并在ML中搜索单词"包管理". (4认同)
  • @kostix很高兴知道,谢谢你的指导.我很困惑因为我认为`go get`意味着*包裹经理 (4认同)
  • @dig,简而言之,Go目前没有包管理工具,*和`go get`不是它*(一个常见的误解是将`go get`视为包管理器).有很多工具可以解决这个问题; 所以你的研究,看看其中的一些,选择你喜欢的并使用它. (3认同)
  • 您无法"冻结"项目依赖项.Go哲学是一切都应该向后兼容.如果您发布了库,则必须确保它与旧版本的公共API保持兼容.如果您需要中断API,那么它是一个新的包,应该有一个新的导入路径.要锁定包,常见的方法是制作本地副本(例如通过分叉). (2认同)
  • Go确实支持Go版本的限制版本控制.使用Gox.x [.x]标记提交(例如Go1.2或Go1.2.2)将使`go get`始终检查匹配释放标记的分支,与"go version"列表相同而不是head.它"应该"用于包括后来Go版本中添加的功能的软件包(例如1.3添加了`sync.Pool`),但许多软件包开发人员只会破坏Go版本更改的API并滥用这一事实. (2认同)

Ina*_*mus 13

您不需要设置 GOPATH 或 GOROOT。GOPATH 默认位于您的用户/主目录下。

如果未设置 GOPATH,则在 Unix 系统上假定为 $HOME/go,在 Windows 上假定为 %USERPROFILE%\go。如果您想使用自定义位置作为工作空间,可以设置 GOPATH 环境变量。


Go 模块

现在有了 Go Modules 支持(从 Go 1.11 开始),因此您不必再使用 GOPATH。例如,您可以转到系统上的任何目录($GOPATH 之外),并且可以在那里初始化一个新的 Go 模块,然后开始在那里工作。不需要 GOPATH。

您只需执行一次(在目录中时):

go mod init
Run Code Online (Sandbox Code Playgroud)

$GOPATH:Go 在其下存储这些文件:

  • 源文件($GOPATH/src)
  • 编译好的包文件($GOPATH/pkg)
  • 可运行文件($GOPATH/bin)

$GOROOT:Go 源代码所在的位置,如 Go 标准库。


另外,要从系统上的任何位置运行任何go installed 可执行文件,您可能需要添加$GOPATH/bin到路径环境变量中,如下所示:

export PATH=$PATH:$(go env GOPATH)/bin
Run Code Online (Sandbox Code Playgroud)

更多信息请查看


Ric*_*777 11

GOPATH允许您在一个地方收集依赖源代码和生成的编译二进制文件.这似乎是一个非常有吸引力的想法.但是,我发现自己正在研究几个完全不相关的Go项目,另一种方法更适合我.

这是与Elwinar的symlnks类似但不同的策略.我在一个空文件夹中启动一个新项目并创建src.然后我将这个名为env.sh的shell脚本放入该文件夹:

if [ `type -p go` = "" ]; then
    export PATH=$PATH:/usr/local/go/bin
fi
export GOPATH=$PWD
export PATH=$PATH:$PWD/bin
Run Code Online (Sandbox Code Playgroud)

每次我开始工作,我都会使用

. env.sh
Run Code Online (Sandbox Code Playgroud)

注意点和空格 - 它们很重要.

现在,我在这个项目上所做的一切都在本文件夹中.它可能不是最广泛使用的策略,但对我来说效果很好.

另外一件事:如果您的依赖项使用环境变量进行测试等,您也可以将它们放入其中env.sh.例如,Gorp

export GORP_TEST_DSN=test/testuser/TestPasswd9
export GO_TEST_DSN=testuser:TestPasswd9@/test
Run Code Online (Sandbox Code Playgroud)