【读书笔记&个人心得】第2章:安装与运行环境
平台与架构
编译器支持的环境
Linux
FreeBSD
Mac OS X(也称为 Darwin)
编译器版本
有 2 个版本的编译器:Go 原生编译器 gc 和非原生编译器 gccgo,其中,gc 版本的编译器已经被移植到 Windows 平台上,并集成在主要发行版中,你也可以通过安装 MinGW 从而在 Windows 平台下使用 gcc 编译器。这两个编译器都是以单通道的形式工作
gc
Go 语言的编译器和链接器都是使用 C 语言编写并产生本地代码(Go 从 1.5 版本开始已经实现自举。Go 语言的编译器和链接器都是 Go 语言编写的)
标记
标记 (Flags) 是指可以通过命令行设置可选参数来影响编译器或链接器的构建过程或得到一个特殊的目标结果
go build 和 go install
从 Go 1.0.3 版本开始,不再使用 8g,8l(用于 x86 32bit 的编译和链接) 之类的指令进行程序的构建,取而代之的是统一的 go build 和 go 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 中找到。
其中,$GOROOT 是环境变量
gccgo
gccgo 编译速度相对 gc 较慢,但产生的本地代码运行要稍微快一点
文件扩展名与包
C 文件使用后缀名 .c,汇编文件使用后缀名 .s,Go 语言源文件的扩展名很显然就是 .go
所有的源代码文件都是通过包 (packages) 来组织。包含可执行代码的包文件在被压缩后使用扩展名 .a(AR 文档)
创建目录时,文件夹名称永远不应该包含空格,而应该使用下划线 "_" 或者其它一般符号代替,也就是说,包路径不能包含空格
Go 环境变量
$GOROOT 表示 Go 在你的电脑上的安装位置
$GOARCH 表示目标机器的处理器架构,它的值可以是 386、amd64 或 arm。
$GOOS 表示目标机器的操作系统,它的值可以是 darwin、freebsd、linux 或 windows。
$GOBIN 表示编译器和链接器的安装位置,默认是 $GOROOT/bin,如果你使用的是 Go 1.0.3 及以后的版本,一般情况下你可以将它的值设置为空,Go 将会使用前面提到的默认值。
目标机器是指你打算运行你的 Go 应用程序的机器。(那这样,我岂不是可以在 windows 把 Go 程序编译为 linux 程序?是的)
交叉编译
Go 编译器支持交叉编译,也就是说你可以在一台机器上构建能够在不同操作系统和处理器架构上运行的应用程序,也就是说编写源代码的机器可以和目标机器有完全不同的特性(操作系统与处理器架构)
$GOHOSTOS:设置本地机器的操作系统名称
$GOHOSTARCH:设置本地机器编译体系结构
这两个变量只有在进行交叉编译的时候才会用到,如果你不进行显示设置,他们的值会和本地机器($GOOS 和 $GOARCH)一样
$GOOS 表示目标机器的操作系统
$GOARCH 表示目标机器的处理器架构
在 Windows 上安装 Go
下载 Windows 系统的一键安装包,你只需要配置 $GOPATH 这一个环境变量就可以开始使用 Go 语言进行开发了
想要测试安装,则可以使用指令 go run 运行 hello_world1.go,果发生错误 fatal error: can’t find import: fmt 则说明你的环境变量没有配置正确。
想要在 Windows 下使用 cgo (调用 C 语言写的代码),则需要安装 MinGW,一般推荐安装 TDM-GCC。
安装目录清单
你的 Go 安装目录 ($GOROOT) 的文件夹结构应该如下所示:
README.md, AUTHORS, CONTRIBUTORS, LICENSE
/bin:包含可执行文件,如:编译器,Go 工具
/doc:包含文档模版
/lib:包含示例程序,代码工具,本地文档等
/misc:包含与支持 Go 编辑器有关的配置文件以及 cgo 的示例
/os_arch:包含标准库的包的对象文件 (.a)----包含可执行代码的包文件在被压缩后使用扩展名 .a
/src:包含源代码构建脚本和标准库的包的完整源代码(Go 是一门开源语言)
/src/cmd:包含 Go 和 C 的编译器和命令行脚本
Go 运行时 (runtime)
runtime 介绍
runtime 其实就是类似 Java 的 JVM(虚拟机)
尽管 Go 编译器产生的是本地可执行代码,这些代码仍旧运行在 Go 的 runtime(这部分的代码可以在 runtime 包中找到)当中。这个 runtime 类似 Java 和 .NET 语言所用到的虚拟机,它负责管理包括内存分配、垃圾回收(第 10.8 节)、栈处理、goroutine、channel、切片 (slice)、map 和反射 (reflection) 等等。
runtime 主要由 C 语言编写(Go 1.5 开始自举),并且是每个 Go 包的最顶级包。你可以在目录 $GOROOT/src/runtime 中找到相关内容。
垃圾回收器
Go 拥有简单却高效的标记-清除回收器。它的主要思想来源于 IBM 的可复用垃圾回收器,旨在打造一个高效、低延迟的并发回收器。目前 gccgo 还没有回收器,同时适用 gc 和 gccgo 的新回收器正在研发中。使用一门具有垃圾回收功能的编程语言不代表你可以避免内存分配所带来的问题,分配和回收内容都是消耗 CPU 资源的一种行为。(CPU 与内存是一组矛盾)
runtime 嵌入到了每一个可执行文件
Go 的可执行文件都比相对应的源代码文件要大很多,这恰恰说明了 Go 的 runtime 嵌入到了每一个可执行文件当中。当然,在部署到数量巨大的集群时,较大的文件体积也是比较头疼的问题。但总的来说,Go 的部署工作还是要比 Java 和 Python 轻松得多。因为 Go 不需要依赖任何其它文件,它只需要一个单独的静态文件,这样你也不会像使用其它语言一样在各种不同版本的依赖文件之间混淆(NodeJS 的依赖版本确实很令人头疼)。