GOPATH那些事儿

1.设置GOPATH有什么意义?
环境变量 GOPATH 的值可以是一个目录的路径,也可以包含多个目录路径,
每个目录都代表 Go 语言的一个工作区(workspace)。这些工作区用于放置 Go 语言的源码文件(source file),
以及安装(install)后的归档文件(archive file,也就是以“.a”为扩展名的文件)和可执行文件(executable file)

这个问题它背后的知识点到底是什么呢
Go 语言项目在其生命周期内的所有操作(编码、依赖管理、构建、测试、安装等)基本上都是围绕着 GOPATH 和工作区进行的。
上述问题主要考察了四个知识点:

1)GO的源码组织方式 ---这里很重要---说明了路径问题
   GO的源码是以  代码包  为基本组织单位,在文件系统中,这些代码包其实是与目录一一对应的。
   目录可以有子目录,所以代码包也可以有子包。
   
   一个代码包中可以包含任意个以.go 为扩展名的源码文件,这些源码文件都需要被声明为属于同一个代码包。
   代码包的名称一般会与这些源码文件所在的目录同名(基本目录名就是包名)。如果不同名,那么在构建、安装的过程中会以代码包名称为准。
   
   每个代码包都会有导入路径。代码包的导入路径是其他代码在使用该包中的程序实体时需要引入的路径。
   在实际使用程序实体之前,我们必须先导入其所在的代码包。具体的方式就是import该代码包的导入路径。
   就像这样:import "github.com/aa/bb"
   
   在工作区中,一个代码包的导入路径实际上就是从src子目录,到该包的实际存储位置的相对路径。
   所以说,Go 语言源码的组织方式就是以环境变量 GOPATH、工作区、src 目录和代码包为主线的。
   一般情况下,Go 语言的源码文件都需要被存放在环境变量 GOPATH 包含的某个工作区(目录)中的 src 目录下的某个代码包(目录)中。


2)源码安装后得结果 (只有在安装后才能被使用)
   源码文件以及安装后的结果文件都会放到哪里呢?我们都知道,源码文件通常会被放在某个工作区的 src 子目录下。
   那么在安装后如果产生了归档文件,就会放进该工作区的 pkg 子目录;
   如果产生了可执行文件,就可能会放进该工作区的 bin 子目录。
   
   归档文件存放的具体位置和规则:
   源码文件会以代码包的形式组织起来,一个代码包其实就对应一个目录。安装某个代码包而产生的归档文件是与这个代码包同名的。
   放置它的相对目录就是该代码包的导入路径的直接父级。比如,一个已存在的代码包的导入路径是 github.com/aa/bb
   那么执行命令:go install github.com/aa/bb生成的归档文件的相对目录就是github.com/aa,文件名为bb.a
   上面这个代码包导入路径还有另外一层含义,那就是:该代码包的源码文件存在于GitHub 网站的aa组的代码仓库bb中。
   
   再说回来,归档文件的相对目录与pkg目录之间还有一级目录,叫做平台相关目录。平台相关目录的名称是由build(也称“构建”)的目标操作系统、下划线和目标计算架构的代号组成的。

   比如,构建某个代码包时的目标操作系统是 Linux,目标计算架构是 64 位的,那么对应的平台相关目录就是 linux_amd64。
   因此,上述代码包的归档文件就会被放置在当前工作区的子目录pkg/linux_amd64/github.com/aa 中。
   
   总之,需要记住的是,某个工作区的 src 子目录下的源码文件在安装后一般会被放置到当前工作区的 pkg 子目录下对应的目录中,
   或者被直接放置到该工作区的 bin 子目录中。
   
3)构建和安装go程序得过程
    构建和安装go程序的过程都是怎样的,以及它们的异同点。
    构建使用命令go build,安装使用命令go install。构建和安装代码包的时候都会执行编译、打包等操作,
    并且这些操作生成的任何文件都会先被保存到某个临时的目录中。
    
    如果构建的是库源码文件,那么操作的结果文件只会存在于临时目录中。这里的构建的主要意义在于检查和验证。
    如果构建的是命令源码文件,那么操作的结果文件会被搬运到那个源码文件所在的目录中。
    
    安装操作会先执行构建,然后还会进行链接操作,并且把结果文件搬运到指定目录。进一步说,
    如果安装的是库源码文件,那么结果文件会被搬运到它所在工作区的 pkg 目录下的某个子目录中。
    如果安装的是命令源码文件,那么结果文件会被搬运到它所在工作区的 bin 目录中,
    或者环境变量GOBIN指向的目录中。
    这里需要记住的是,构建和安装的不同之处,以及执行相应命令后得到的结果文件都会出现在哪里。

4)go build的可选项得用途和用法
在运行gobuild命令的时候,默认不会编译目标代码包所依赖的那些代码包。当然,
如果被依赖的代码包的归档文件不存在,或者源码文件有了变化,那它还是会被编译。
如果要强制编译它们,可以在执行命令的时候加入标记-a。此时,不但目标代码包总是会被
编译,它依赖的代码包也总会被编译,即使依赖的是标准库中的代码包也是如此。
另外,如果不但要编译依赖的代码包,还要安装它们的归档文件,那么可以加入标记-i。
那么我们怎么确定哪些代码包被编译了呢?有两种方法。
1. 运行go build命令时加入标记-x,这样可以看到go build命令具体都执行了哪些操作。
另外也可以加入标记-n,这样可以只查看具体操作而不执行它们。
2. 运行go build命令时加入标记-v,这样可以看到go build命令编译的代码包的名称。
它在与-a标记搭配使用时很有用。
-a 强制编译,包括依赖包
-i 编译时需要编译归档文件
-x 查看go build 具体执行了哪些操作
-n 查看go build 具体操作而不执行它们
-v 查看go build命令编译的代码包的名称。可以与-a标记搭配使用

go get命令详解
命令go get会自动从一些主流公用代码仓库(比如 GitHub)下载目标代码包,并把它们安装
到环境变量GOPATH包含的第 1 工作区的相应目录中。如果存在环境变量GOBIN,那么仅包含命
令源码文件的代码包会被安装到GOBIN指向的那个目录。

最常用的几个标记有下面几种。
-u:下载并安装代码包,不论工作区中是否已存在它们。
-d:只下载代码包,不安装代码包。
-fix:在下载代码包后先运行一个用于根据当前 Go 语言版本修正代码的工具,然后再安装代码包。
-t:同时下载测试所需的代码包。
-insecure:允许通过非安全的网络协议下载和安装代码包。HTTP 就是这样的协议。

Go 语言官方提供的go get命令是比较基础的,其中并没有提供依赖管理的功能。目前
GitHub 上有很多提供这类功能的第三方工具,比如glide、gb以及官方出品的dep、vgo等
等,它们在内部大都会直接使用go get。

有时候,我们可能会出于某种目的变更存储源码的代码仓库或者代码包的相对路径。这时,为了
让代码包的远程导入路径不受此类变更的影响,我们会使用自定义的代码包导入路径。
对代码包的远程导入路径进行自定义的方法是:在该代码包中的库源码文件的包声明语句的右边加入导入注释,
像这样:package semaphore // import  "golang.org/x/sync/semaphore"

而 Go 语言官网 golang.org 下的路径 /x/sync/semaphore 并不是存放semaphore包的真实地址。我们称之为代码包的自定义导入路径。
不过,这还需要在 golang.org 这个域名背后的服务端程序上添加一些支持才能使这条命令成功。

总结
Go 语言提供的很多工具都是在GOPATH 和工作区的基础上运行的,比如上面提到的go build、go install和go get,这三个命令也是我们最常用到的。

说到 Go 程序中的依赖管理,其实还有很多问题值得我们探索。
1. Go 语言在多个工作区中查找依赖包的时候是以怎样的顺序进行的?

例如 a 依赖 b ,b依赖c 
那么 会先查找c包,那在工作区是如何查找这个依赖包c的呢?
首先在查找依赖包的时候,总是会先查找 GOROOT目录,也就是go语言的安装目录,如果没有找到依赖的包,才到工作区去找相应的包。
在工作区中是按照设置的先后顺序来查找的,也就是会从第一个开始,依次查找,如果找到就不再继续查找,如果没有找到,就报错了。

go get 会下载代码包到src目录,但是只会下载到第一个工作区目录。
在Go语言程序中,每个包都有一个全局唯一的导入路径。导入语句中类似"github.com/xxxx/tem"的字符串对应包的导入路径。
Go语言的规范并没有定义这些字符串的具体含义或包来自哪里,它们是由构建工具来解释的。
一个导入路径代表一个目录中的一个或多个Go源文件。
除了包的导入路径,每个包还有一个包名,包名一般是短小的名字(并不要求包名是唯一的),包名在包的声明处指定。

当你在代码中引用一个 package 时,golang 的查找顺序是:
当前包下的 vendor 目录。
向上级目录查找,直到找到 src 下的 vendor 目录。
在 GOPATH 下面查找依赖包。
在 GOROOT 目录下查找

2. 如果在多个工作区中都存在导入路径相同的代码包会产生冲突吗?
不冲突,因为按顺序找到所需要的包就不往后找了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值