Go语言核心36讲-01工作区和GOPATH

01 | 工作区和GOPATH

说明: 该系列文章是个人购买了极客时间Go语言专栏由赫林老师著作的 Go语言核心36讲系列的个人总结归纳,算是自己对知识付费的一个负责吧。希望通过这样的笔记和该系列文章能加强自己对Go语言的核心知识的理解和运用。

首先我们去安装Go环境时都回去官网下载安装包的二进制包运行安装就可以使用了

然后,解压缩包、放置目录、配置环境变量,并通过在命令行中输入:

命令行运行下面命令:

go version

终端会输出:

go version go1.10 darwin/amd64

一般情况下,我们应该配置 3 个环境变量,即 GOROOT、GOPATH 和 GOBIN。其中,GOPATH 背后的概念是最多的,也是最重要的。


一. 设置 GOPATH 有什么意义?

环境变量 GOPATH 的值可以是一个目录的路径,也可以包含多个目录路径,每个目录都代表 Go 语言的一个工作区(workspace)。

这些工作区用于放置 Go 语言的源码文件(src目录),以及安装(install)后的归档文件(pkg目录)和可执行文件(bin目录)。

Go 语言项目在其生命周期内的所有操作(编码、依赖管理、构建、测试、安装等)基本上都是围绕着 GOPATH 和工作区进行的。


二. 知识扩展(干货)

1. Go 语言源码的组织方式

与许多编程语言一样,Go 语言的源码是以代码包为基本组织单位的。在文件系统中,这些代码包其实是与目录一一对应的。目录可以有子目录,所以代码包也可以有子包。

一个代码包中可以包含任意个以.go 为扩展名的源码文件,这些源码文件都需要被声明为属于同一个代码包。代码包的名称一般会与这些源码文件所在的目录同名。如果不同名,那么在构建、安装的过程中会以代码包名称为准。

看下面的目录结构:

图中 三处红线标记处名称都是一样的,对应上面的解释即为:

翻译图文对应(说人话)

一个代码包目录 api 下有子目录 captcha,即代码包 api 也可以有 captcha 子包。

一个代码包 captcha 中包含 captcha.go 的源码文件,它声明属于代码包名为(右上角 package 处就是声明此包名) captcha。

当然你可以不同名去声明 package,但是你要保证该目录下所有的源码文件的包声明必须一致。最终包名以你声明的为准!

2. 源码安装后的结果

源码文件以及安装后的结果文件都会放到哪里呢?我们都知道,源码文件通常会被放在某个工作区的 src 子目录下。

那么在安装后如果产生了归档文件,就会放进该工作区的 pkg 子目录;如果产生了可执行文件,就可能会放进该工作区的 bin 子目录。

所以这里就应该有 说人话 环节:

  • #### src 目录: 用于以代码包的形式组织并保存Go 源码文件的。
  • #### pkg 目录: 用于存放通过 go install 安装后的代码包的归档文件(指 “.a” 结尾的文件)。
  • #### bin 目录: 与 pkg 目录相似,通过 go install 命令安装后,保存有Go命令源码文件生成的可执行文件。

来看下面的一个例子:

一个已存在的代码包的导入路径是:

github.com/labstack/echo

然后执行命令是这样的:

go install github.com/labstack/echo

那么生成的归档文件的相对目录就是 github.com/labstack/,文件名为 echo.a

by the way, 上面这个代码导入路径另外含义有:该代码的源码文件存在于 GitHub 网站的 labstack 组的代码仓库 echo 中。

再说回来,归档文件的相对目录与 pkg 目录之间还有一级目录,叫做平台相关目录。平台相关目录的名称是由 build(也称“构建”)的目标操作系统、下划线和目标计算架构的代号组成的。

比如,构建某个代码包时的目标操作系统是 Linux,目标计算架构是 64 位的,那么对应的平台相关目录就是 linux_amd64。(mac 就应该是 darwin_amd64)

因此,上述代码包的归档文件就会被放置在当前工作区的子目录 pkg/linux_amd64/github.com/labstack 中。

3. 理解构建和安装 Go 程序的过程

  • go build 用于构建
  • go install 用于安装

构建和安装代码包的时候都会执行编译、打包等操作,并且这些操作生成的任何文件都会先被保存到某个临时的目录中。

  • 1. 如果构建(build)的是库源码文件,那么操作的结果文件只会存在于临时目录中。
  • 2. 如果构建(build)的是命令源码文件(main.go),那么操作的结果文件会被搬运到那个源码文件文件所在的目录中。
  • 3. 安装操作(install)会先执行构建,然后还会进行链接操作,并且把结果文件搬运到指定目录。

进一步说,如果安装(install)的是库源码文件,那么结果文件会被搬运到它所在工作区的 pkg 目录下的某个子目录中。

如果安装(install)的是命令源码文件(main.go),那么结果文件会被搬运到它所在工作区的 bin 目录中,或者环境变量。

4. go build 和 go get 命令一些可选项的用途和用法

go build 命令

-a // 不但目标代码包总是会被编译,它依赖的代码包也总会被编译,即使依赖的是标准库中的代码包也是如此。

-i // 如果不但要编译依赖的代码包,还要安装它们的归档文件,那么可以加入标记

-x // 可以看见 go build 命令具体都执行了哪些操作。另外也可以加入标记

-n // 这样可以只查看具体操作而不执行它们。

-v // 可以看见  go build 命令编译的代码包的名称它在与 -a 搭配很有用

go get 命令

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

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