Go 核心36讲笔记 01

工作区和 GOPATH

  • GOROOT:Go 语言安装根目录的路径,也就是 GO 语言的安装路径。
  • GOPATH:若干工作区目录的路径。是我们自己定义的工作空间。
  • GOBIN:GO 程序生成的可执行文件(executable file)的路径。

你可以把 GOPATH 简单理解成 Go 语言的工作目录,它的值是一个目录的路径,也可以是多个目录路径,每个目录都代表 Go 语言的一个工作区(workspace)。

这些工作区去放置

  1. Go 语言的源码文件(source file)
  2. 安装(install)后的归档文件(archive file,也就是以“.a”为扩展名的文件)
  3. 可执行文件(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)
}

相关

如果觉得我的文章对您有用,请在支付宝公益平台找个项目捐点钱。 @Victor Feb 26, 2019

奉献爱心