## Go 编译器
Go 编译器在 go 工具的帮助下执行,该工具不仅生成可执行文件,还执行更多的操作。
> Tip: 本节中使用的`unsafe.go`文件不包含任何内容特殊代码–所提供的命令将在每个有效的 Go 源文件上运行。
你可以通过`go tool compile` 命令编译 Go 源代码。你将得到一个**目标文件**,这将是一个以`.o`扩展结尾的文件。在 macOS Mojave 环境下执行的下一个命令的输出中对此进行了说明:
```shell
$ go tool compile unsafe.go
$ ls -l unsafe.o
-rw-r--r-- 1 mtsouk staff 6926 Jan 22 21:39 unsafe.o
$ file unsafe.o
unsafe.o: current ar archive
```
目标文件是包含目标代码的文件,该目标代码是可重定位格式的机器代码,在大多数情况下,这些代码不能直接执行。可重定位格式的最大优点是在链接阶段它只需要较少的内存。
如果你在运行`go tool compile`的时候加上了`-pack`标志,你将会得到**压缩文件**而非目标文件:
```shell
$ go tool compile -pack unsafe.go
$ ls -l unsafe.a
-rw-r--r-- 1 mtsouk staff 6926 Jan 22 21:40 unsafe.a
$ file unsafe.a
unsafe.a: current ar archive
```
压缩文件是包含一个或多个文件的二进制文件,主要是
用于将多个文件分组为一个文件。这些格式之一是 `ar`,它是 Go 使用的格式。
你可以像这样打印出一个 `.a` 压缩文件的内容:
```shell
$ ar t unsafe.a
__.PKGDEF
_go_.o
```
`go tool compile` 另一个真正有价值的命令行标志是`-race`,它使你能够检测**竞争条件**。你将在第10章*Go的并发性-高级主题*中了解有关竞争条件以及为什么要避免竞争条件的更多信息。
本章的最后讨论汇编语言和节点树的时候,你还会学到一个更多有用的`go tool compile`命令。不过目前你可以尝试一下下面的命令:
```
$ go tool compile -S unsafe.go
```
你可能会发现,以上命令的输出会让你难以理解,这正说明了Go可以很好地帮你隐藏不必要的复杂性,除非你要求Go展示出来。
- 介绍
- 1 Go与操作系统
- 01.1 Go的历史
- 01.2 Go的未来
- 01.3 Go的优点
- 01.3.1 Go是完美的么
- 01.3.2 什么是预处理器
- 01.3.3 godoc
- 01.4 编译Go代码
- 2 理解 Go 的内部构造
- Go 编译器
- Go 的垃圾回收
- 三色算法
- 有关 Go 垃圾收集器操作的更多信息
- Maps, silces 与 Go 垃圾回收器
- Unsafe code
- 有关 unsafe 包
- 另一个 usafe 包的例子
- 从 Go 调用 C 代码
- 在同一文件用 Go 调用 C 代码
- 在单独的文件用 Go 调用 C 代码
- 从 C 调用 Go 代码
- Go 包
- C 代码
- defer 关键字
- 用 defer 打印日志
- Panic 和 Recover
- 单独使用 Panic 函数
- 两个好用的 UNIX 工具
- strace
- dtrace
- 配置 Go 开发环境
- go env 命令
- Go 汇编器
- 节点树
- 进一步了解 Go 构建
- 创建 WebAssembly 代码
- 对 Webassembly 的简单介绍
- 为什么 WebAssembly 很重要
- Go 与 WebAssembly
- 示例
- 使用创建好的 WebAssembly 代码
- Go 编码风格建议
- 练习和相关链接
- 本章小结
- 3 Go基本数据类型
- 03.1 Go循环
- 03.1.1 for循环
- 03.1.2 while循环
- 03.1.3 range关键字
- 03.1.4 for循环代码示例
- 03.3 Go切片
- 03.3.1 切片基本操作
- 03.3.2 切片的扩容
- 03.3.3 字节切片
- 03.3.4 copy()函数
- 03.3.5 多维切片
- 03.3.6 使用切片的代码示例
- 03.3.7 使用sort.Slice()排序
- 03.4 Go 映射(map)
- 03.4.1 Map值为nil的坑
- 03.4.2 何时该使用Map?
- 03.5 Go 常量
- 03.5.1 常量生成器:iota
- 03.6 Go 指针
- 03.7 时间与日期的处理技巧
- 03.7.1 解析时间
- 03.7.2 解析时间的代码示例
- 03.7.3 解析日期
- 03.7.4 解析日期的代码示例
- 03.7.5 格式化时间与日期
- 03.8 延伸阅读
- 03.9 练习
- 03.10 本章小结
- 9 并发-Goroutines,Channel和Pipeline
- 09.1 关于进程,线程和Go协程
- 09.1.1 Go调度器
- 09.1.2 并发与并行
- 09.2 Goroutines
- 09.2.1 创建一个Goroutine
- 09.2.2 创建多个Goroutine
- 09.3 优雅地结束goroutines
- 09.3.1 当Add()和Done()的数量不匹配时会发生什么?
- 09.4 Channel(通道)
- 09.4.1 通道的写入
- 09.4.2 从通道接收数据
- 09.4.3 通道作为函数参数传递
- 09.5 管道
- 09.6 延展阅读
- 09.7 练习
- 09.8 本章小结