工作区和 GOPATH
- GOROOT:Go 语言安装根目录的路径,也就是 GO 语言的安装路径。
- GOPATH:若干工作区目录的路径。是我们自己定义的工作空间。
- GOBIN:GO 程序生成的可执行文件(executable file)的路径。
你可以把 GOPATH 简单理解成 Go 语言的工作目录,它的值是一个目录的路径,也可以是多个目录路径,每个目录都代表 Go 语言的一个工作区(workspace)。
这些工作区去放置
- Go 语言的源码文件(source file)
- 安装(install)后的归档文件(archive file,也就是以“.a”为扩展名的文件)
- 可执行文件(executable file)。
Go 语言项目在其生命周期内的所有操作(编码、依赖管理、构建、测试、安装等)基本上都是围绕着 GOPATH 和工作区进行的。
知识扩展
Go 语言源码的组织方式
- Go 语言的源码也是以代码包为基本组织单位的。
- 在文件系统中,这些代码包其实是与目录一一对应的。
- 由于目录可以有子目录,所以代码包也可以有子包。
- 一个代码包中可以包含任意个以 .go 为扩展名的源码文件,这些源码文件都需要被声明属于同一个代码包。
- 代码包的名称一般会与源码文件所在的目录同名。如果不同名,那么在构建、安装的过程中会以代码包名称为准。
- 每个代码包都会有导入路径。
- 代码包的导入路径是其他代码在使用该包中的程序实体时,需要引入的路径。
- 在实际使用程序实体之前,我们必须先导入其所在的代码包。
- 引入方式就是
import
,例如 import "github.com/labstack/echo"
- 在工作区中,一个代码包的导入路径实际上就是从
src
子目录,到该包的实际存储位置的相对路径。
Go 语言源码的组织方式就是以环境变量 GOPATH、工作区、src 目录和代码包为主线的。一般情况下,Go 语言的源码文件都需要被存放在环境变量 GOPATH 包含的某个工作区(目录)中的 src 目录下的某个代码包(目录)中。
了解源码安装后的结果
源码文件通常会被放在某个工作区的 src 子目录下。安装后如果产生了归档文件(以“.a”为扩展名的文件),就会放进该工作区的 pkg 子目录;如果产生了可执行文件,就可能会放进该工作区的 bin 子目录。
源码文件会以代码包的形式组织起来,一个代码包其实就对应一个目录。安装某个代码包而产生的归档文件是与这个代码包同名的。放置它的相对目录就是该代码包的导入路径的直接父级。
比如,一个已存在的代码包的导入路径是:github.com/labstack/echo
执行命令 go install github.com/labstack/echo
生成的归档文件的相对目录就是 github.com/labstack
文件名是 echo.a
。
上面这个代码包导入路径还有另外一层含义,那就是:该代码包的源码文件存在于 GitHub 网站的 labstack 组的代码仓库 echo 中。
归档文件的相对目录与 pkg 目录之间还有一级目录,叫做平台相关目录。平台相关目录的名称是由 build(也称“构建”)的目标操作系统、下划线和目标计算架构的代号组成的。
总之,你需要记住的是,某个工作区的 src 子目录下的源码文件在安装后一般会被放置到当前工作区的 pkg 子目录下对应的目录中,或者被直接放置到该工作区的 bin 子目录中。
理解构建和安装 Go 程序的过程
- 构建使用命令
go build
,安装使用命令 go install
。构建和安装代码包的时候都会执行编译、打包等操作,这些操作生成的任何文件都会先被保存到某个临时的目录中。
- 构建
- 如果构建的是库源码文件,那么操作后产生的结果文件只会存在于临时目录中。这里的构建的主要意义在于检查和验证。
- 如果构建的是命令源码文件,那么操作的结果文件会被搬运到源码文件所在的目录中。
- 安装
- 安装操作会先执行构建,然后还会进行链接操作,并且把结果文件搬运到指定目录。
- 如果安装的是库源码文件,那么结果文件会被搬运到它所在工作区的 pkg 目录下的某个子目录中。
- 如果安装的是命令源码文件,那么结果文件会被搬运到它所在工作区的 bin 目录中,或者环境变量 GOBIN 指向的目录中。
命令源码文件
源码文件分三种:命令源码文件、库源码文件和测试源码文件。
如果一个源码文件声明属于 main 包,并且包含一个无参数声明且无结果声明的 main 函数,那么它就是命令源码文件。
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
直接用 go run hello.go
来查看运行结果。
当需要模块化编程时,会把代码拆分到多个文件,甚至不同的代码包中。但无论怎样,对于一个独立的程序来说,命令源码文件永远只有一个。如果有与命令源码文件同包的源码文件,那么它们也应该声明属于 main 包。
知识精讲
命令源码文件怎样接收参数
package main
import (
"flag"
"fmt"
)
var name string
func init() {
flag.StringVar(&name, "name", "everyone", "The greeting object.")
}
func main() {
flag.Parse()
fmt.Printf("Hello, %s!\n", name)
}
相关