.GO 语言安装的时候主要有三个环境变量:
GOROOT、GOPATH 和 GOBIN
通过 go env 可以查看go语言的一系列的环境变量的配置.
go env
GOROOT
:代表go的安装路径,一般你安装完go语言之后就有了。
GOPATH
:一个目录路径,也可以包含多个目录路径,每个目录都代表了go语言的一个“工作区”。目录下面有三个目录,src,bin,pkg。
src
: 用来存放源代码文件。
bin
: 目录里面存放的都是通过 go install 命令安装后,由 Go 命令源码文件生成的可执行文件。
有两种情况下,bin 目录会变得没有意义。
当设置了有效的 GOBIN 环境变量以后,bin 目录就变得没有意义。
如果 GOPATH 里面包含多个工作区路径的时候,必须设置 GOBIN 环境变量,否则就无法安装 Go 程序的可执行文件。
pkg:用来存放通过 go install 命令安装后的代码包的归档文件(.a 文件)
GOBIN:存放可执行文件的文件目录。
Go 的源码文件分类:
(1)命令源码文件:
声明自己属于 main 代码包、包含无参数声明和结果声明的 main 函数。 命令源码文件被安装以后,GOPATH 如果只有一个工作区,那么相应的 可执行文件会被存放当前工作区的 bin 文件夹下;如果有多个工作区, 就会安装到 GOBIN 指向的目录下。
(2)库源码文件
库源码文件就是不具备命令源码文件上述两个特征的源码文件。存在于某个代码包中的普通的源码文件。
(3)测试源码文件
名称以 _test.go 为后缀的代码文件,并且必须包含 Test 或者 Benchmark 名称前缀的函数。
详情可以参照
理解内容:
$GOPATH/pkg/$GOOS_$GOARCH
中,同样以代码包为组织形式。同时这里有两个隐藏的环境变量, GOOS
和 GOARCH
。这两个环境变量是不用我们设置的,系统就默认的。 GOOS
是 Go 所在的操作系统类型, GOARCH
是 Go 所在的计算架构。平台相关目录是以 $GOOS_$GOARCH
命名的,Mac 平台上这个目录名就是 darwin_amd64。 go源码文件
func TestXXX( t *testing.T) { }
名称以 Test 为名称前缀的函数,只能接受 *testing.T 的参数,这种测试函数是功能测试函数。
func BenchmarkXXX( b *testing.B) { }
名称以 Benchmark 为名称前缀的函数,只能接受 *testing.B 的参数,这种测试函数是性能测试函数。
因此:命令源码文件是可以单独运行的。可以使用 go run 命令直接运行,也可以通过 go build 或 go install 命令得到相应的可执行文件。所以命令源码文件是可以在机器的任何目录下运行的。
包名 main 则告诉我们它是一个可独立运行的包,它在编译后会产生可执行文件。除了 main 包之外,其它的包最后都会生成 *.a 文件(也就是包文件)并放置在 $GOPATH/pkg/$GOOS_$GOARCH
中(以 Mac 为例就是 $GOPATH/pkg/darwin_amd64
)。
image
中间产生两个临时文件。
go build 用于编译我们指定的源码文件或代码包以及它们的依赖包。,但是注意如果用来编译非命令源码文件,即库源码文件,go build 执行完是不会产生任何结果的。这种情况下,go build 命令只是检查库源码文件的有效性,只会做检查性的编译,而不会输出任何结果文件。
go build 编译命令源码文件,则会在该命令的执行目录中生成一个可执行文件
go run 和go build的前几步都一样,只是最后go run 执行可执行文件,go build 不执行。
image
go install 命令是用来编译并安装代码包或者源码文件的。
安装操作会先执行构建,然后还会进行链接操作,并且把结果文件搬运到指定目录。
前面几步依旧和 go run 、go build 完全一致,只是最后一步的差别,go install 会把命令源码文件安装到当前工作区的 bin 目录(如果 GOPATH 下有多个工作区,就会放在 GOBIN 目录下)。如果是库源码文件,就会被安装到当前工作区的 pkg 的平台相关目录下。
例如:go install github.com/labstack/echo
image
go install 命令不支持针对库源码文件的安装操作。
go get 命令会把当前的代码包下载到 $GOPATH 中的第一个工作区的 src 目录中,并安装。
如果在 go get 下载过程中加入-d 标记,那么下载操作只会执行下载动作,而不执行安装动作。
-u标记,加上它可以利用网络来更新已有的代码包及其依赖包。
image
package HelloGo import "fmt" func PrintHello(){ fmt.Println("Hello Go") }
这时候如果你想调用这个包,代码应该怎么写,
import HelloGo? 还是import hello
答案肯定是import hello的,因为GOPATH的特性,只会按照目录来查找包,但你调用的时候就不能用目录名字来调用了:
package main import "fmt" import "hello" func main() { fmt.Println("Hello, world!") HelloGo.PrintHello() //导入包的时候用文件夹名字,调用函数用package的名字 }
在运行go build命令的时候,默认不会编译目标代码包所依赖的那些代码包,如果归档文件已经存在的话。如果被依赖的代码包的归档文件不存在,或者源码文件有了变化,那它还是会被编译。常用参数说明:
-a : 可以强制编译依赖的代码包
-i : 不但要编译依赖的代码包,还要安装它们的归档文件
-x : 查看go build命令具体执行了哪些操作
-n : 同上,只查看操作,但是不实际执行
-v : 可以看到go build命令编译的代码包的名称。搭配-a参数使用时很有用
命令go get会自动下载代码包,并把它们安装到环境变量GOPATH包含的第1工作区的相应目录中。如果存在环境变量GOBIN,那么仅包含命令源码文件的代码包会被安装到GOBIN指向的那个目录。常用参数说明:
-u : 下载并安装代码包,不论是否已存在
-d : 只下载代码包,不安装代码包
-fix : 在下载代码包后先运行一个用于根据当前Go语言版本修正代码的工具,然后再安装代码包
-t : 同时下载测试所需的代码包
-insecure : 允许通过非安全的网络协议下载和安装代码包。比如:HTTP。
如果你想把你编写的(被托管在不同的代码托管网站上的)代码包的远程导入路径统一起来,或者不希望让你的代码包中夹杂某个代码托管网站的域名,那么你可以选择自定义你的代码包远程导入路径。这种自定义的实现手段叫做“导入注释”。
比如代码实际存储的位置是:github.com/golang/sync/
但是安装的时候实际使用的命令是:go get golang.org/x/sync。这里就隐藏了github.com的域名,以及后面的部分路径golang。
导入注释必须出现在源码文件的代码包声明语句的右边,是一条单行注释。被双引号包裹的是一个符合导入路径语法规则的字符串。下面是 github.com/golang/sync 下 semaphore/semaphore.go 里的导入注释:
package semaphore // import “golang.org/x/sync/semaphore”
这样加入导入注释后,就无法用github的地址来下载这个包了。但是也无法用自定义的路径来下载这个包,应该自定义的路径的网址还不能响应这个请求
编写一个可处理HTTP请求的程序。将对这个url响应的请求头中加入如下的一行内容:
这行内容会被视为HTML文档的元数据。这个就是go get命令的文档中要求的写法。它的模式是这样的:
content属性中的import-prefix的位置上填入自定义的远程代码包导入路径的前缀。而vsc代表与版本控制系统有关的标识,比如git。至于repo-root,它应该是与该处理程序关联的路径对应的Github网站的URL,即实际网址。
这么做的好处是,可以强化你的品牌,而不是某个代码托管网站的。顺便还可以隐藏掉用户ID,也就是域名后的部分路径。
最主要的是,使你的代码包导入路径整齐划一,如果代码包分散在不同的远程路径的话。
欢迎关注我们的微信公众号,每天学习Go知识