logo资料库

the-way-to-go.pdf

第1页 / 共475页
第2页 / 共475页
第3页 / 共475页
第4页 / 共475页
第5页 / 共475页
第6页 / 共475页
第7页 / 共475页
第8页 / 共475页
资料共475页,剩余部分请下载后查看
目录
第一部分:学习 Go 语言
第二部分:语言的核心结构与技术
第三部分:Go 高级编程
第四部分:实际应用
附录
索引
前言
用更少的代码,更短的编译时间,创建运行更快的程序,享受更多的乐趣
链接
1.1 起源与发展
时间轴:
链接
1.2 语言的主要特性与发展的环境和影响因素
1.2.1 影响 Go 语言发展的早期编程语言
1.2.2 为什么要创造一门编程语言
1.2.3 Go 语言的发展目标
1.2.4 指导设计原则
1.2.5 语言的特性
1.2.6 语言的用途
1.2.7 关于特性缺失
1.2.8 使用 Go 语言编程
1.2.9 小结
链接
2.1 平台与架构
链接
2.2 Go 环境变量
链接
2.3 在 Linux 上安装 Go
链接
2.4 在 Mac OS X 上安装 Go
链接
2.5 在 Windows 上安装 Go
链接
2.6 安装目录清单
链接
2.7 Go 运行时(runtime)
链接
2.8 Go 解释器
链接
3.0 编辑器、集成开发环境与其它工具
链接
3.1 Go 开发环境的基本要求
链接
3.2 编辑器和集成开发环境
3.2.1 LiteIDE
3.2.2 GoClipse
链接
3.3 调试器
链接
3.4 构建并运行 Go 程序
链接
3.5 格式化代码
链接
3.6 生成代码文档
链接
3.7 其它工具
链接
3.8 Go 性能说明
链接
3.9 与其它语言进行交互
3.9.1 与 C 进行交互
3.9.2 与 C++ 进行交互
链接
4.1 文件名、关键字与标识符
链接
4.2 Go 程序的基本结构和要素
4.2.1 包的概念、导入与可见性
4.2.2 函数
4.2.3 注释
4.2.4 类型
4.2.5 Go 程序的一般结构
4.2.6 类型转换
4.2.7 Go 命名规范
链接
4.3 常量
链接
4.4 变量
4.4.1 简介
4.4.2 值类型和引用类型
4.4.3 打印
4.4.4 简短形式,使用 := 赋值操作符
4.4.5 init 函数
链接
4.5 基本类型和运算符
4.5.1 布尔类型 bool
4.5.2 数字类型
4.5.2.1 整型 int 和浮点型 float
4.5.2.2 复数
4.5.2.3 位运算
4.5.2.4 逻辑运算符
4.5.2.5 算术运算符
4.5.2.6 随机数
4.5.3 运算符与优先级
4.5.4 类型别名
4.5.5 字符类型
链接
4.6 字符串
链接
4.7 strings 和 strconv 包
4.7.1 前缀和后缀
4.7.2 字符串包含关系
4.7.3 判断子字符串或字符在父字符串中出现的位置(索引)
4.7.4 字符串替换
4.7.5 统计字符串出现次数
4.7.6 重复字符串
4.7.7 修改字符串大小写
4.7.8 修剪字符串
4.7.9 分割字符串
4.7.10 拼接 slice 到字符串
4.7.11 从字符串中读取内容
4.7.12 字符串与其它类型的转换
链接
4.8 时间和日期
链接
4.9 指针
链接
5.0 控制结构
链接
5.1 if-else 结构
链接
5.2 测试多返回值函数的错误
链接
5.3 switch 结构
链接
5.4 for 结构
5.4.1 基于计数器的迭代
练习题
5.4.2 基于条件判断的迭代
5.4.3 无限循环
5.4.4 for-range 结构
链接
5.5 Break 与 continue
链接
5.6 标签与 goto
链接
6.0 函数
链接
6.1 介绍
链接
6.2 函数参数与返回值
6.2.1 按值传递(call by value) 按引用传递(call by reference)
6.2.2 命名的返回值(named return variables)
6.2.3 空白符(blank identifier)
6.2.4 改变外部变量(outside variable)
链接
6.3 传递变长参数
链接
6.4 defer 和追踪
链接
6.5 内置函数
链接
6.6 递归函数
练习题
链接
6.7 将函数作为参数
链接
6.8 闭包
链接
6.9 应用闭包:将函数作为返回值
链接
6.10 使用闭包调试
链接
6.11 计算函数执行时间
链接
6.12 通过内存缓存来提升性能
链接
7.0 数组与切片
链接
7.1 声明和初始化
7.1.1 概念
7.1.2 数组常量
7.1.3 多维数组
7.1.4 将数组传递给函数
链接
7.2 切片
7.2.1 概念
7.2.2 将切片传递给函数
7.2.3 用 make() 创建一个切片
7.2.4 new() 和 make() 的区别
7.2.5 多维 切片
7.2.6 bytes 包
链接
7.3 For-range 结构
链接
7.4 切片重组(reslice)
链接
7.5 切片的复制与追加
链接
7.6 字符串、数组和切片的应用
7.6.1 从字符串生成字节切片
7.6.2 获取字符串的某一部分
7.6.3 字符串和切片的内存结构
7.6.4 修改字符串中的某个字符
7.6.5 字节数组对比函数
7.6.6 搜索及排序切片和数组
7.6.7 append 函数常见操作
7.6.8 切片和垃圾回收
链接
8.0 Map
链接
8.1 声明、初始化和 make
8.1.1 概念
8.1.2 map 容量
8.1.3 用切片作为 map 的值
链接
8.2 测试键值对是否存在及删除元素
链接
8.3 for-range 的配套用法
链接
8.4 map 类型的切片
链接
8.5 map 的排序
链接
8.6 将 map 的键值对调
链接
9.0 包(package)
链接
9.1 标准库概述
链接
9.2 regexp 包
链接
9.3 锁和 sync 包
链接
9.4 精密计算和 big 包
链接
9.5 自定义包和可见性
链接
9.6 为自定义包使用 godoc
链接
9.7 使用 go install 安装自定义包
链接
9.8 自定义包的目录结构、go install 和 go test
9.8.1 自定义包的目录结构
9.8.2 本地安装包
9.8.3 依赖系统的代码
链接
9.9 通过 Git 打包和安装
9.9.1 安装到 GitHub
9.9.2 从 GitHub 安装
链接
9.10 Go 的外部包和项目
链接
9.11 在 Go 程序中使用外部库
链接
10 结构(struct)与方法(method)
链接
10.1 结构体定义
链接
10.2 使用工厂方法创建结构体实例
10.2.1 结构体工厂
10.2.2 map 和 struct vs new() 和 make()
链接
10.3 使用自定义包中的结构体
链接
10.4 带标签的结构体
链接
10.5 匿名字段和内嵌结构体
10.5.1 定义
10.5.2 内嵌结构体
10.5.3 命名冲突
链接
10.6 方法
10.6.1 方法是什么
10.6.2 函数和方法的区别
10.6.3 指针或值作为接收者
10.6.4 方法和未导出字段
10.6.5 内嵌类型的方法和继承
10.6.6 如何在类型中嵌入功能
10.6.7 多重继承
10.6.8 通用方法和方法命名
10.6.9 和其他面向对象语言比较 Go 的类型和方法
链接
10.7 类型的 String() 方法和格式化描述符
链接
10.8 垃圾回收和 SetFinalizer
链接
11 接口(Interfaces)与反射(reflection)
链接
11.1 接口是什么
链接
11.2 接口嵌套接口
链接
11.3 类型断言:如何检测和转换接口变量的类型
链接
11.4 类型判断:type-switch
链接
11.5 测试一个值是否实现了某个接口
链接
11.6 使用方法集与接口
链接
11.7 第一个例子:使用 Sorter 接口排序
链接
11.8 第二个例子:读和写
链接
11.9 空接口
11.9.1 概念
11.9.2 构建通用类型或包含不同类型变量的数组
11.9.3 复制数据切片至空接口切片
11.9.4 通用类型的节点数据结构
11.9.5 接口到接口
链接
11.10 反射包
11.10.1 方法和类型的反射
11.10.2 通过反射修改(设置)值
11.10.3 反射结构
链接
11.11 Printf 和反射
链接
11.12 接口与动态类型
11.12.1 Go 的动态类型
11.12.2 动态方法调用
11.12.3 接口的提取
11.12.4 显式地指明类型实现了某个接口
11.12.5 空接口和函数重载
11.12.6 接口的继承
链接
11.13 总结:Go 中的面向对象
链接
11.14 结构体、集合和高阶函数
链接
12 读写数据
链接
12.1 读取用户的输入
链接
12.2 文件读写
12.2.1 读文件
12.2.2 compress包:读取压缩文件
12.2.3 写文件
链接
12.3 文件拷贝
链接
12.4 从命令行读取参数
12.4.1 os 包
12.4.2 flag 包
链接
12.5 用 buffer 读取文件
链接
12.6 用切片读写文件
链接
12.7 用 defer 关闭文件
链接
12.8 使用接口的实际例子:fmt.Fprintf
链接
12.9 JSON 数据格式
反序列化:
解码任意的数据:
解码数据到结构
编码和解码流
链接
12.10 XML 数据格式
链接
12.11 用 Gob 传输数据
链接
12.12 Go 中的密码学
链接
13 错误处理与测试
链接
13.1 错误处理
13.1.1 定义错误
13.1.2 用 fmt 创建错误对象
链接
13.2 运行时异常和 panic
链接
13.3 从 panic 中恢复(Recover)
链接
13.4 自定义包中的错误处理和 panicking
链接
13.5 一种用闭包处理错误的模式
链接
13.6 启动外部命令和程序
链接
13.7 Go 中的单元测试和基准测试
链接
13.8 测试的具体例子
链接
13.9 用(测试数据)表驱动测试
链接
13.10 性能调试:分析并优化 Go 程序
13.10.1 时间和内存消耗
13.10.2 用 go test 调试
13.10.3 用 pprof 调试
链接
14 协程(goroutine)与通道(channel)
链接
14.1 并发、并行和协程
14.1.1 什么是协程
14.1.2 并发和并行的差异
14.1.3 使用 GOMAXPROCS
14.1.4 如何用命令行指定使用的核心数量
14.1.5 Go 协程(goroutines)和协程(coroutines)
链接
14.2 协程间的信道
14.2.1 概念
14.2.2 通信操作符 <-
14.2.3 通道阻塞
14.2.4 通过一个(或多个)通道交换数据进行协程同步。
14.2.5 同步通道-使用带缓冲的通道
14.2.6 协程中用通道输出结果
14.2.7 信号量模式
14.2.8 实现并行的 for 循环
14.2.9 用带缓冲通道实现一个信号量
14.2.10 给通道使用 for 循环
14.2.11 通道的方向
链接
14.3 协程的同步:关闭通道-测试阻塞的通道
链接
14.4 使用 select 切换协程
练习:
链接
14.5 通道、超时和计时器(Ticker)
链接
14.6 协程和恢复(recover)
链接
14.7 新旧模型对比:任务和worker
链接
14.8 惰性生成器的实现
链接
14.9 实现 Futures 模式
链接
15.0 网络,模板和网页应用
链接
15.1 tcp服务器
链接
15.2 一个简单的网页服务器
链接
15.3 访问并读取页面
链接
15.4 写一个简单的网页应用
16 常见的陷阱与错误
链接
16.1 误用短声明导致变量覆盖
链接
16.2 误用字符串
链接
16.3 发生错误时使用defer关闭一个文件
链接
16.4 何时使用new()和make()
链接
16.5 不需要将一个指向切片的指针传递给函数
链接
16.6 使用指针指向接口类型
链接
16.7 使用值类型时误用指针
链接
16.8 误用协程和通道
链接
16.9 闭包和协程的使用
链接
16.10 糟糕的错误处理
16.10.1 不要使用布尔值:
16.10.2 避免错误检测使代码变得混乱:
链接
17 模式
链接
17.1 关于逗号ok模式
链接
18 出于性能考虑的实用代码片段
链接
18.1 字符串
链接
18.2 数组和切片
链接
18.3 映射
链接
18.4 结构体
链接
18.5 接口
链接
18.6 函数
链接
18.7 文件
链接
18.8 协程(goroutine)与通道(channel)
链接
18.9 网络和网页应用
18.9.1 模板:
链接
18.10 其他
链接
18.11 出于性能考虑的最佳实践和建议
链接
关于本文·16.10.2小结糟糕错误处理的一些见解
关于16.10.2的第一个代码示例
关于16.10.2的第二个代码示例
关于错误处理的一些延伸
⽬目录 前⾔言 第⼀一部分:学习 Go 语⾔言 第1章:Go 语⾔言的起源,发展与普及 1.1 起源与发展 1.2 语⾔言的主要特性与发展的环境和影响因素 第2章:安装与运⾏行行环境 2.1 平台与架构 2.2 Go 环境变量量 2.3 在 Linux 上安装 Go 2.4 在 Mac OS X 上安装 Go 2.5 在 Windows 上安装 Go 2.6 安装⽬目录清单 2.7 Go 运⾏行行时(runtime) 2.8 Go 解释器器 第3章:编辑器器、集成开发环境与其它⼯工具 3.1 Go 开发环境的基本要求 3.2 编辑器器和集成开发环境 3.3 调试器器 3.4 构建并运⾏行行 Go 程序 3.5 格式化代码 3.6 ⽣生成代码⽂文档 3.7 其它⼯工具 3.8 Go 性能说明 3.9 与其它语⾔言进⾏行行交互 第⼆二部分:语⾔言的核⼼心结构与技术 第4章:基本结构和基本数据类型 4.1 ⽂文件名、关键字与标识符 4.2 Go 程序的基本结构和要素 4.3 常量量 4.4 变量量 4.5 基本类型和运算符 4.6 字符串串 4.7 strings 和 strconv 包 4.8 时间和⽇日期 4.9 指针 第5章:控制结构
5.1 if-else 结构 5.2 测试多返回值函数的错误 5.3 switch 结构 5.4 for 结构 5.5 Break 与 continue 5.6 标签与 goto 第6章:函数(function) 6.1 介绍 6.2 函数参数与返回值 6.3 传递变⻓长参数 6.4 defer 和追踪 6.5 内置函数 6.6 递归函数 6.7 将函数作为参数 6.8 闭包 6.9 应⽤用闭包:将函数作为返回值 6.10 使⽤用闭包调试 6.11 计算函数执⾏行行时间 6.12 通过内存缓存来提升性能 第7章:数组与切⽚片 7.1 声明和初始化 7.2 切⽚片 7.3 For-range 结构 7.4 切⽚片重组(reslice) 7.5 切⽚片的复制与追加 7.6 字符串串、数组和切⽚片的应⽤用 第8章:Map 8.1 声明、初始化和 make 8.2 测试键值对是否存在及删除元素 8.3 for-range 的配套⽤用法 8.4 map 类型的切⽚片 8.5 map 的排序 8.6 将 map 的键值对调 第9章:包(package) 9.1 标准库概述 9.2 regexp 包 9.3 锁和 sync 包 9.4 精密计算和 big 包 9.5 ⾃自定义包和可⻅见性 9.6 为⾃自定义包使⽤用 godoc 9.7 使⽤用 go install 安装⾃自定义包 9.8 ⾃自定义包的⽬目录结构、go install 和 go test 9.9 通过 Git 打包和安装 9.10 Go 的外部包和项⽬目 9.11 在 Go 程序中使⽤用外部库
第10章:结构(struct)与⽅方法(method) 10.1 结构体定义 10.2 使⽤用⼯工⼚厂⽅方法创建结构体实例例 10.3 使⽤用⾃自定义包中的结构体 10.4 带标签的结构体 10.5 匿匿名字段和内嵌结构体 10.6 ⽅方法 10.7 类型的 String() ⽅方法和格式化描述符 10.8 垃圾回收和 SetFinalizer 第11章:接⼝口(interface)与反射(reflection) 11.1 接⼝口是什什么 11.2 接⼝口嵌套接⼝口 11.3 类型断⾔言:如何检测和转换接⼝口变量量的类型 11.4 类型判断:type-switch 11.5 测试⼀一个值是否实现了了某个接⼝口 11.6 使⽤用⽅方法集与接⼝口 11.7 第⼀一个例例⼦子:使⽤用 Sorter 接⼝口排序 11.8 第⼆二个例例⼦子:读和写 11.9 空接⼝口 11.10 反射包 11.11 Printf 和反射 11.12 接⼝口与动态类型 11.13 总结:Go 中的⾯面向对象 11.14 结构体、集合和⾼高阶函数 第三部分:Go ⾼高级编程 第12章:读写数据 12.1 读取⽤用户的输⼊入 12.2 ⽂文件读写 12.3 ⽂文件拷⻉贝 12.4 从命令⾏行行读取参数 12.5 ⽤用 buffer 读取⽂文件 12.6 ⽤用切⽚片读写⽂文件 12.7 ⽤用 defer 关闭⽂文件 12.8 使⽤用接⼝口的实际例例⼦子:fmt.Fprintf 12.9 格式化 JSON 数据 12.10 XML 数据格式 12.11 ⽤用 Gob 传输数据 12.12 Go 中的密码学 第13章:错误处理理与测试 13.1 错误处理理 13.2 运⾏行行时异常和 panic 13.3 从 panic 中恢复(Recover) 13.4 ⾃自定义包中的错误处理理和 panicking
13.5 ⼀一种⽤用闭包处理理错误的模式 13.6 启动外部命令和程序 13.7 Go 中的单元测试和基准测试 13.8 测试的具体例例⼦子 13.9 ⽤用(测试数据)表驱动测试 13.10 性能调试:分析并优化 Go 程序 第14章:协程(goroutine)与通道(channel) 14.1 并发、并⾏行行和协程 14.2 使⽤用通道进⾏行行协程间通信 14.3 协程同步:关闭通道-对阻塞的通道进⾏行行测试 14.4 使⽤用 select 切换协程 14.5 通道,超时和计时器器(Ticker) 14.6 协程和恢复(recover) 14.7 新旧模型对⽐比:任务和worker 14.8 惰性⽣生成器器的实现 14.9 实现 Futures 模式 第15章:⽹网络、模版与⽹网⻚页应⽤用 15.1 tcp服务器器 15.2 ⼀一个简单的web服务器器 15.3 访问并读取⻚页⾯面数据 15.4 写⼀一个简单的⽹网⻚页应⽤用 第四部分:实际应⽤用 第16章:常⻅见的陷阱与错误 16.1 误⽤用短声明导致变量量覆盖 16.2 误⽤用字符串串 16.3 发⽣生错误时使⽤用defer关闭⼀一个⽂文件 16.4 何时使⽤用new()和make() 16.5 不不需要将⼀一个指向切⽚片的指针传递给函数 16.6 使⽤用指针指向接⼝口类型 16.7 使⽤用值类型时误⽤用指针 16.8 误⽤用协程和通道 16.9 闭包和协程的使⽤用 16.10 糟糕的错误处理理 第17章:模式 17.1 关于逗号ok模式 第18章:出于性能考虑的实⽤用代码⽚片段 18.1 字符串串 18.2 数组和切⽚片 18.3 映射 18.4 结构体 18.5 接⼝口 18.6 函数 18.7 ⽂文件
18.8 协程(goroutine)与通道(channel) 18.9 ⽹网络和⽹网⻚页应⽤用 18.10 其他 18.11 出于性能考虑的最佳实践和建议 第19章:构建⼀一个完整的应⽤用程序 第20章:Go 语⾔言在 Google App Engine 的使⽤用 第21章:实际部署案例例 附录 A 代码引⽤用 B 有趣的 Go 引⽤用 C 代码示例例列列表 D 书中的包引⽤用 E 书中的⼯工具引⽤用 F 常⻅见问题解答 G 习题答案 H 参考⽂文献 索引
前⾔言 ⽤用更更少的代码,更更短的编译时间,创建运⾏行行更更快的程序,享受更更多 的乐趣 对于学习 Go 编程语⾔言的爱好者来说,这本书⽆无疑是最适合你的⼀一本书籍,这⾥里里包含了了当前最全⾯面的学 习资源。本书通过对官⽅方的在线⽂文档、名⼈人博客、书籍、相关⽂文章以及演讲的资料料收集和整理理,并结合 我⾃自身在软件⼯工程、编程语⾔言和数据库开发的授课经验,将这些零碎的知识点组织成系统化的概念和技 术分类来进⾏行行讲解。 随着软件规模的不不断扩⼤大,诸多的学者和⾕谷歌的开发者们在公司内部的软件开发过程中开始经历⼤大量量的 挫折,在诸多问题上都不不能给出令⼈人满意的解决⽅方案,尤其是在使⽤用 C++ 来开发⼤大型的服务端软件时, 情况更更是不不容乐观。由于⼆二进制⽂文件⼀一般都是⾮非常巨⼤大的,因此需要耗费⼤大量量的时间在编译这些⽂文件 上,同时编程语⾔言的设计思想也已经⾮非常陈旧,这些情况都充分证明了了现有的编程语⾔言已不不符合时下的 ⽣生产环境。尽管硬件在过去的⼏几⼗十年年中有了了⻜飞速的发展,但⼈人们依旧没有找到机会去改变 C++ 在软件开 发的重要地位,并在实际开发过程中忍受着它所带来的令⼈人头疼的⼀一些问题。因此学者们坐下来总结出 了了现在⽣生产环境与软件开发之间的主要⽭矛盾,并尝试设计⼀一⻔门全新的编程语⾔言来解决这些问题。 以下就是他们讨论得出的对编程语⾔言的设计要求: 能够以更更快的速度开发软件 开发出的软件能够很好地在现代的多核计算机上⼯工作 开发出的软件能够很好地在⽹网络环境下⼯工作 使⼈人们能够享受软件开发的过程 Go 语⾔言就在这样的环境下诞⽣生了了,它让⼈人感觉像是 Python 或 Ruby 这样的动态语⾔言,但却⼜又拥有像 C 或者 Java 这类语⾔言的⾼高性能和安全性。 Go 语⾔言出现的⽬目的是希望在编程领域创造最实⽤用的⽅方式来进⾏行行软件开发。它并不不是要⽤用奇怪的语法和 晦涩难懂的概念来从根本上推翻已有的编程语⾔言,⽽而是建⽴立并改善了了 C、Java、C# 中的许多语法⻛风格。 它提倡通过接⼝口来针对⾯面向对象编程,通过 goroutine 和 channel 来⽀支持并发和并⾏行行编程。 这本书是为那些想要学习 Go 这⻔门全新的,迷⼈人的和充满希望的编程语⾔言的开发者量量身定做的。当然, 你在学习 Go 语⾔言之前需要具备⼀一些关于编程的基础知识和经验,并且拥有合适的学习环境,但你并不不 需要对 C 或者 Java 或其它类似的语⾔言有⾮非常深⼊入的了了解。 对于那些熟悉 C 或者⾯面向对象编程语⾔言的开发者,我们将会在本书中⽤用 Go 和⼀一些编程语⾔言的相关概念 进⾏行行⽐比较(书中会使⽤用⼤大家所熟知的缩写 “OO” 来表示⾯面向对象)。 本书将会从最基础的概念讲起,同时也会讨论⼀一些类似在应⽤用 goroutine 和 channel 时有多少种不不同的 模式,如何在 Go 语⾔言中使⽤用⾕谷歌 API,如何操作内存,如何在 Go 语⾔言中进⾏行行程序测试和如何使⽤用模 板来开发 Web 应⽤用这些⾼高级概念和技巧。 在本书的第⼀一部分,我们将会讨论 Go 语⾔言的起源(第 1 章),以及如何安装 Go 语⾔言(第 2 章)和开 发环境(第 3 章)。
在本书的第⼆二部分,我们将会带领你贯穿 Go 语⾔言的核⼼心思想,譬如简单与复杂类型(第 4、7、8 章),控制结构(第 5 章),函数(第 6 章),结构与⽅方法(第 10 章)和接⼝口(第 11 章)。我们会 对 Go 语⾔言的函数式和⾯面向对象编程进⾏行行透彻的讲解,包括如何使⽤用 Go 语⾔言来构造⼤大型项⽬目(第 9 章)。 在本书的第三部分,你将会学习到如何处理理不不同格式的⽂文件(第 12 章)和如何在 Go 语⾔言中巧妙地使 ⽤用错误处理理机制(第 13 章)。然后我们会对 Go 语⾔言中最值得称赞的设计 goroutine 和 channel 进⾏行行 并发和多核应⽤用的基本技巧的讲解(第 14 章)。最后,我们会讨论如何将 Go 语⾔言应⽤用到分布式和 Web 应⽤用中的相关⽹网络技巧(第 15 章)。 我们会在本书的第四部分向你展示许多 Go 语⾔言的开发模式和⼀一些编码规范,以及⼀一些⾮非常有⽤用的代码 ⽚片段(第 18 章)。在前⾯面章节完成对所有的 Go 语⾔言技巧的学习之后,你将会学习如何构造⼀一个完整 Go 语⾔言项⽬目(第 19 章),然后我们会介绍⼀一些关于 Go 语⾔言在云(Google App Engine)⽅方⾯面的应⽤用 (第 20 章)。在本书的最后⼀一章(第 21 章),我们会讨论⼀一些在全世界范围内已经将 Go 语⾔言投⼊入实 际开发的公司和组织。本书将会在最后给出⼀一些对 Go 语⾔言爱好者的引⽤用,Go 相关包和⼯工具的参考, 以及章节练习的答案和所有参考资源和⽂文献的清单。 Go 语⾔言有⼀一个被称之为 “没有废物” 的宗旨,就是将⼀一切没有必要的东⻄西都去掉,不不能去掉的就⽆无底线 地简化,同时追求最⼤大程度的⾃自动化。他完美地诠释了了敏敏捷编程的 KISS 秘诀:短⼩小精悍! Go 语⾔言通过改善或去除在 C、C++ 或 Java 中的⼀一些所谓“开放”特性来让开发者们的⼯工作更更加便便利利。这 ⾥里里只举例例其中的⼏几个,⽐比如对于变量量的默认初始化,内存分配与⾃自动回收,以及更更简洁却不不失健壮的控 制结构。同时我们也会发现 Go 语⾔言旨在减少不不必要的编码⼯工作,这使得 Go 语⾔言的代码更更加简洁,从 ⽽而⽐比传统的⾯面向对象语⾔言更更容易易阅读和理理解。 与 C++ 或 Java 这些有着庞⼤大体系的语⾔言相⽐比,Go 语⾔言简洁到可以将它整个的装⼊入你的⼤大脑中,⽽而且⽐比 学习 Scala(Java 的并发语⾔言)有更更低的⻔门槛,真可谓是 21 世纪的 C 语⾔言! 作为⼀一⻔门系统编程语⾔言,你不不应该为 Go 语⾔言的⼤大多数代码示例例和练习都和控制台有着密不不可分的关系 ⽽而感到惊奇,因为提供平台依赖性的 GUI(⽤用户界⾯面)框架并不不是⼀一个简单的任务。有许多由第三⽅方发 起的 GUI 框架项⽬目正在如⽕火如荼地进⾏行行中,或许我们会在不不久的将来看到⼀一些可⽤用的 Go 语⾔言 GUI 框 架。不不过现阶段的 Go 语⾔言已经提供了了⼤大量量有关 Web ⽅方⾯面的功能,我们可以通过它强⼤大的 http 和 template 包来达到 Web 应⽤用的 GUI 实现。 我们会经常涉及到⼀一些关于 Go 语⾔言的编码规范,了了解和使⽤用这些已经被⼴广泛认同的规范应该是你学习 阶段最重要的实践。我会在书中尽量量使⽤用已经讲解的概念或者技巧来解释相关的代码示例例,以避免你在 不不了了解某些⾼高级概念的情况下⽽而感到迷茫。 我们通过 227 个完整的代码示例例和书中的解释说明来对所有涉及到的概念和技巧进⾏行行彻底的讲解,你可 以下载这些代码到你的电脑上运⾏行行,从⽽而加深对概念的理理解。 本书会尽可能地将前后章节的内容联系起来,当然这也同时要求你通过学习不不同的知识来对⼀一个问题提 出尽可能多的解决⽅方案。记住,学习⼀一⻔门新语⾔言的最佳⽅方式就是实践,运⾏行行它的代码,修改并尝试更更多 的⽅方案。因此,你绝对不不可以忽略略书中的 130 个代码练习,这将对你学习好 Go 语⾔言有很⼤大的帮助。⽐比 如,我们就为斐波那契算法提供了了 13 个不不同的版本,⽽而这些版本都使⽤用了了不不同的概念和技巧。 你可以通过访问本书的 官⽅方⽹网站 下载书中的代码(译者注:所有代码⽂文件已经包括在 GitHub 仓库 中),并获得有关本书的勘误情况和内容更更新。 为了了让你在成为 Go 语⾔言⼤大师的道路路上更更加顺利利,我们会专注于⼀一些特别的章节以提供 Go 语⾔言开发模 式的最佳实践,同时也会帮助初学者逃离⼀一些语⾔言的陷阱。第 18 章可以作为你在开发时的⼀一个参考⼿手 册,因为当中包含了了众多的有价值的代码⽚片段以及相关的解释说明。
最后要说明的是,你可以通过完整的索引来快速定位你需要阅读的章节。书中所有的代码都在 Go1.4 版 本下测试通过。 这⾥里里有⼀一段来⾃自在 C++、Java 和 Python 领域众所周知的专家 Bruce Eckel 的评论: “作为⼀一个有着 C/C++ 背景的开发者,我在使⽤用 Go 语⾔言时仿佛呼吸到了了新鲜空⽓气⼀一般,令⼈人⼼心旷神 怡。我认为使⽤用 Go 语⾔言进⾏行行系统编程开发⽐比使⽤用 C++ 有着更更显著的优势,因为它在解决⼀一些很难⽤用 C++ 解决的问题的同时,让我的⼯工作变得更更加⾼高效。我并不不是说 C++ 的存在是⼀一个错误,相反地,我认 为这是历史发展的必然结果。当我深陷在 C 语⾔言这⻔门略略微⽐比汇编语⾔言好⼀一点的泥泥潭时,我坚信任何语⾔言 的构造都不不可能⽀支持⼤大型项⽬目的开发。像垃圾回收或并发语⾔言⽀支持这类东⻄西,在当时都是极其荒谬的主 意,根本没有⼈人在乎。C++ 向⼤大型项⽬目开发迈出了了重要的第⼀一步,带领我们⾛走进这个⼴广袤⽆无垠的世界。 很庆幸 Stroustrup 做了了让 C++ 兼容 C 语⾔言以能够让其编译 C 程序这个正确的决定。我们当时需要 C++ 的出现。” “之后我们学到了了更更多。我们毫⽆无疑问地接受了了垃圾回收,异常处理理和虚拟机这些当年年⼈人们认为只有疯⼦子 才会想的东⻄西。C++ 的复杂程度(新版的 C++ 甚⾄至更更加复杂)极⼤大的影响了了软件开发的⾼高效性,这使得 它再也不不再适合这个时代。⼈人们不不再像过往那样认同在 C++ 中兼容使⽤用 C 语⾔言的⽅方法,认为这些⼯工作 只是在浪费时间,牺牲⼈人们的努⼒力力。就在此时,Go 语⾔言已经成功地解决了了 C++ 中那些本打算解决却未 能解决的关键问题。” 我⾮非常想要向发明这⻔门精湛的语⾔言的 Go 开发团队表示真挚的感谢,尤其是团队的领导者 Rob Pike、 Russ Cox 和 Andrew Gerrand,他们阐述的例例⼦子和说明都⾮非常的完美。同时,我还要感谢 Miek Gieben、Frank Muller、Ryanne Dolan 和 Satish V.J. 给予我巨⼤大的帮助,还有那些 golang-nuts 邮件 列列表⾥里里的所有的成员。 欢迎来到 Go 语⾔言开发的奇妙世界! 链接 ⽬目录 下⼀一部分: Go 语⾔言的起源,发展与普及
分享到:
收藏