2.1 平台与架构

Go 语言开发团队开发了适用于以下操作系统的编译器:

  • Linux
  • FreeBSD
  • Mac OS X(也称为 Darwin)

目前有2个版本的编译器:Go 原生编译器 gc 和非原生编译器 gccgo,这两款编译器都是在类 Unix 系统下工作 。其中,gc 版本的编译器已经被移植到 Windows 平台上,并集成在主要发行版中,你也可以通过安装 MinGW 从而在 Windows 平台下使用 gcc 编译器。这两个编译器都是以单通道的形式工作。
你可以获取以下平台上的 Go 1.4 源码和二进制文件:

  • Linux 2.6+:amd64、386 和 arm 架构
  • Mac OS X(Snow Leopard + Lion):amd64 和 386 架构
  • Windows 2000+:amd64 和 386 架构

对于非常底层的纯 Go 语言代码或者包而言,在各个操作系统平台上的可移植性是非常强的,只需要将源码拷贝到相应平台上进行编译即可,或者可以使用交叉编译来构建目标平台的应用程序(第 2.2 节)。但如果你打算使用 cgo 或者类似文件监控系统的软件,就需要根据实际情况进行相应地修改了。

  1. Go 原生编译器 gc:
    主要基于 Ken Thompson 先前在 Plan 9 操作系统上使用的 C 工具链。
    Go 语言的编译器和链接器都是使用 C 语言编写并产生本地代码,Go 不存在自我引导之类的功能。因此如果使用一个有不同指令集的编译器来构建 Go 程序,就需要针对操作系统和处理器架构(32 位操作系统或 64 位操作系统)进行区别对待。( 译者注:Go从1.5版本开始已经实现自举。Go语言的编译器和链接器都是Go语言编写的
    这款编译器使用非分代、无压缩和并行的方式进行编译,它的编译速度要比 gccgo 更快,产生更好的本地代码,但编译后的程序不能够使用 gcc 进行链接。
    编译器目前支持以下基于 Intel 或 AMD 处理器架构的程序构建。
    2、安装与运行环境 - 图1
    图2.1 gc 编译器支持的处理器架构
    当你第一次看到这套命名系统的时候你会觉得很奇葩,不过这些命名都是来自于 Plan 9 项目。

    g = 编译器:将源代码编译为项目代码(程序文本)
    l = 链接器:将项目代码链接到可执行的二进制文件(机器代码)

  2. (相关的 C 编译器名称为 6c、8c 和 5c,相关的汇编器名称为 6a、8a 和 5a)
    标记(Flags) 是指可以通过命令行设置可选参数来影响编译器或链接器的构建过程或得到一个特殊的目标结果。
    可用的编译器标记如下:

    flags:
    -I 针对包的目录搜索
    -d 打印声明信息
    -e 不限制错误打印的个数
    -f 打印栈结构
    -h 发生错误时进入恐慌(panic)状态
    -o 指定输出文件名 // 详见第3.4节
    -S 打印产生的汇编代码
    -V 打印编译器版本 // 详见第2.3节
    -u 禁止使用 unsafe 包中的代码
    -w 打印归类后的语法解析树
    -x 打印 lex tokens

  3. 从 Go 1.0.3 版本开始,不再使用 8g,8l 之类的指令进行程序的构建,取而代之的是统一的 go buildgo install 等命令,而这些指令会自动调用相关的编译器或链接器。
    如果你想获得更深层次的信息,你可以在目录 $GOROOT/src/cmd 下找到编译器和链接器的源代码。Go 语言本身是由 C 语言开发的,而不是 Go 语言(Go 1.5 开始自举)。词法分析程序是 GNU bison,语法分析程序是名为 $GOROOT/src/cmd/gc/go.y 的 yacc 文件,它会在同一目录输出 y.tab.{c,h} 文件。如果你想知道更多有关构建过程的信息,你可以在 $GOROOT/src/make.bash 中找到。
    大部分的目录都包含了名为 doc.go 的文件,这个文件提供了更多详细的信息。

  4. gccgo 编译器:
    一款相对于 gc 而言更加传统的编译器,使用 GCC 作为后端。GCC 是一款非常流行的 GNU 编译器,它能够构建基于众多处理器架构的应用程序。编译速度相对 gc 较慢,但产生的本地代码运行要稍微快一点。它同时也提供一些与 C 语言之间的互操作性。
    从 Go 1 版本开始,gc 和 gccgo 在编译方面都有等价的功能。
  5. 文件扩展名与包(package):
    Go 语言源文件的扩展名很显然就是 .go
    C 文件使用后缀名 .c,汇编文件使用后缀名 .s。所有的源代码文件都是通过包(packages)来组织。包含可执行代码的包文件在被压缩后使用扩展名 .a(AR 文档)。
    Go 语言的标准库(第 9.1 节)包文件在被安装后就是使用这种格式的文件。
    注意 当你在创建目录时,文件夹名称永远不应该包含空格,而应该使用下划线 “_” 或者其它一般符号代替。

2.2 Go 环境变量

Go 开发环境依赖于一些操作系统环境变量,你最好在安装 Go 之前就已经设置好他们。如果你使用的是 Windows 的话,你完全不用进行手动设置,Go 将被默认安装在目录 c:/go 下。这里列举几个最为重要的环境变量:

  • $GOROOT 表示 Go 在你的电脑上的安装位置,它的值一般都是 $HOME/go,当然,你也可以安装在别的地方。
  • $GOARCH 表示目标机器的处理器架构,它的值可以是 386、amd64 或 arm。
  • $GOOS 表示目标机器的操作系统,它的值可以是 darwin、freebsd、linux 或 windows。
  • $GOBIN 表示编译器和链接器的安装位置,默认是 $GOROOT/bin,如果你使用的是 Go 1.0.3 及以后的版本,一般情况下你可以将它的值设置为空,Go 将会使用前面提到的默认值。

目标机器是指你打算运行你的 Go 应用程序的机器。
Go 编译器支持交叉编译,也就是说你可以在一台机器上构建运行在具有不同操作系统和处理器架构上运行的应用程序,也就是说编写源代码的机器可以和目标机器有完全不同的特性(操作系统与处理器架构)。
为了区分本地机器和目标机器,你可以使用 $GOHOSTOS$GOHOSTARCH 设置本地机器的操作系统名称和编译体系结构,这两个变量只有在进行交叉编译的时候才会用到,如果你不进行显示设置,他们的值会和本地机器($GOOS$GOARCH)一样。

  • $GOPATH 默认采用和 $GOROOT 一样的值,但从 Go 1.1 版本开始,你必须修改为其它路径。它可以包含多个 Go 语言源码文件、包文件和可执行文件的路径,而这些路径下又必须分别包含三个规定的目录:srcpkgbin,这三个目录分别用于存放源码文件、包文件和可执行文件。
  • $GOARM 专门针对基于 arm 架构的处理器,它的值可以是 5 或 6,默认为 6。
  • $GOMAXPROCS 用于设置应用程序可使用的处理器个数与核数,详见第 14.1.3 节。

在接下来的章节中,我们将会讨论如何在 Linux、Mac OS X 和 Windows 上安装 Go 语言。在 FreeBSD 上的安装和 Linux 非常类似。开发团队正在尝试将 Go 语言移植到其它例如 OpenBSD、DragonFlyBSD、NetBSD、Plan 9、Haiku 和 Solaris 操作系统上,你可以在这个页面找到最近的动态:Go Porting Efforts

2.3 安装 Go

如果你能够自己下载并编译 Go 的源代码的话,对你来说是非常有教育意义的。
不过,实战中,我们更推荐使用这个页面找到安装指南和下载地址:Download the Go distribution。(不会或者无法翻墙的同学,可以使用这个连接)

对于版本的选择,我建议大家使用1.13或更高的版本。当然最新版本是1.15.6。

Golang的安装非常方便,在Linux环境下,解压即可使用,Mac和Windows则是安装好后就可以使用。
但是Golang的编译和执行,都依赖Go环境变量,因此需要设置环境变量。
主要的变量有:
GOROOT,golang的安装目录,如果是Linux,则是解压的目录,如果是mac,默认是/usr/local/go
GOPATH,golang的代码保存的位置,可以自定义。
GOBIN,一般设置为GOPATH/bin目录,为Golang的项目编译安装的默认位置
另外GOROOT/bin和GOBIN目录,都需要添加到PATH环境变量中。(Windows类似)

安装完成之后,输入go version,可以提示实际golang的版本即可:

  1. (base) [jpbirdy@jpbirdyShuzhiPro:go]$ go version
  2. go version go1.13.4 darwin/amd64
  3. (base) [jpbirdy@jpbirdyShuzhiPro:go]$

如果不知道如何设置环境变量,请自行baidu。

2.4 集成开发环境

目前兼容Golang的IDE比较多,具体:

Goland Jetbrains的开发工具,收费,但是非常好用。熟悉Jetbrains工具包的同学或不知道使用什么工具的同学可以考虑Goland。
image.png
GoClipse 是一款 Eclipse IDE 的插件,拥有非常多的特性以及通过 GoCode 来实现代码补全功能。熟悉ECLIPSE的同学可以考虑。
image.png
VSCode 前端开发利器,开源,免费。熟悉VSCode的同学可以使用。

2.5 代码管理

这里提一下Golang对于二方包和三方包的管理和依赖的管理。
包是结构化代码的一种方式:每个程序都由包(通常简称为 pkg)的概念组成,可以使用自身的包或者从其它包中导入内容。

如同其它一些编程语言中的类库或命名空间的概念,每个 Go 文件都属于且仅属于一个包。一个包可以由许多以 .go 为扩展名的源文件组成,因此文件名和包名一般来说都是不相同的。

你必须在源文件中非注释的第一行指明这个文件属于哪个包,如:package mainpackage main表示一个可独立执行的程序,每个 Go 应用程序都包含一个名为 main 的包。

一个包可以引用其他包,但是包之间不能循环引用,否则会出现编译错误。

通常,包需要保存在一个被git托管的平台中,最常见的则是github(包括golang的源码本身),因此发布一个自己的包,只需要提交到自己对应的github代码仓库即可。当然非github的其他git管理的仓库均可。

在go 1.11之前,golang只能通过github的直接依赖,而github的代码变动很快,因此经常出现过去可以编译的包,一段时间之后无法编译,因为依赖的包进行了升级或修改导致报错。
在go 1.11之后,golang引入了module的概念,可以通过go.mod文件的编写,描述项目的依赖情况。并且对于包的依赖,被确定在了git的某一个tag或者某一次commit,避免了代码的版本问题。(更多git的问题,可自行baidu或提问)