为什么会有Go语言
2007 年(2007 年 9 月 20 日下午的一次讨论),当时 Go 语言的三位创始人是想通过开发一种新型的语言来解决 Google 在软件开发中面临的问题:
-
多核硬件架构;
-
超大规模分布式计算集群;
-
Web 开发模式导致的前所未有的开发规模和更新速度。
Go特性
-
简单:Go 语言特性始终保持在少且足够的水平。知名 Go 开发者戴维·切尼(Dave Cheney)曾说过:“大多数编程语言创建伊始都致力于成为一门简单的语言,但最终都只是满足于做一个强大的编程语言”。Go 不仅一开始简单,直到现在也都保持“简单”。
- 较之 C 语言的 37 个关键字,Java的50个关键字, C++ 11 的 84 个关键字,Go 只有 25 个关键字,主流编程语言最少;
- 内置垃圾收集,降低开发人员内存管理的心智负担;
- 首字母大小写决定可见性,无需通过额外关键字修饰;
- 变量初始为类型零值,避免以随机值作为初值的问题;
- 内置数组边界检查,极大减少越界访问带来的安全隐患;
- 内置并发支持,简化并发程序设计;
- 内置接口类型,为组合的设计哲学奠定基础;
- 原生提供完善的工具链,开箱即用;
-
显式:指任何代码行为都需开发者明确知晓,不存在因“暗箱操作”而导致可维护性降低和不安全的结果
- 以显式的方式通过转型统一参与计算各个变量的类型。
- Go 语言采用了显式的基于值比较的错误处理方案。
-
组合:类型定义与方法是正交(独立且解耦的,一个事物的变化不影响另外一个事物)。
- 支撑组合的设计提供了类型嵌入(Type Embedding),快速让一个新类型“复用”其他类型已经实现的能力,实现功能的垂直扩展。
- 通过新类型实例调用方法时,方法的匹配主要取决于方法名字,而不是类型。
- 水平组合是一种能力委托(Delegate),我们通常使用接口类型来实现水平组合。
-
并发:CPU 向多核方向发展这一趋势的结果
- 采用了用户层轻量级线程,Go 将之称为 goroutine。
- 并发是一种程序结构设计的方法,它使得并行成为可能。
-
面向工程:
-
生产力:
- 如果源文件导入它不使用的包,则程序将无法编译。
- 有简单清晰的依赖管理,去除包的循环依赖,包路径是唯一的,而包名不必唯一的。
- 故意不支持默认函数参数。
- 增加类型别名(type alias),支持大规模代码库的重构。
- 自动加入分号,能让编译器做的事不需要交给开发者。
-
高效:Go 语言提供了足以让所有其它主流语言开发人员羡慕的工具链,工具链涵盖了编译构建、代码格式化、包依赖管理、静态代码检查、测试、文档生成与查看、性能剖析、语言服务器、运行时程序跟踪等方方面面。
-
带着Java特性写Go的误区
- 大量使用共享内存的方式进行并发控制,而忽略了 Go 内置的 CSP 并发机制;
- Java 程序员在编写 Go 程序喜欢在方法调用间直接传递数组,导致大量内存复制。其实,与 Java 不同,Go 的数组参数是通过值复制来传递的。
- Java 程序员用 Go 时也总是喜欢创建一个只包含接口定义的包,以处理依赖关系。而 这 Go 中其实大可不必,在 Go 中接口的实现对接口定义是没有依赖的。
Go语言里程碑
| 2009 年 11 月 10 日 | 谷歌官方宣布 Go 语言项目开源,之后这一天也被 Go 官方确定为 Go 语言的诞生日。 |
|---|---|
| 2012 年 3 月 28 日 | Go 1.0 版本正式发布 |
| 2015年 | Go 1.5 版本实现自举 |
| 2018年 | Go 1.11 版本 go module 解决 Go 包依赖问题,在项目引入 go.mod 以及在 go.mod 中明确项目所依赖的第三方包和版本,项目的构建就将摆脱 GOPATH 的束缚,实现精准的可重现构建。 |
| 2021年 | Go 1.16 版本 Go module 已经成为了 Go 默认的包依赖管理机制和 Go 源码构建机制。 |
Go语言适用场景
- 云原生基础设施、中间件与云服务领域
- DevOps/SRE、区块链、命令行交互程序(CLI)、Web 服务,数据处理
Go版本发布策略
- 每年发布两次大版本上,一般是在二月份和八月份发布
- 使用次新版,即最新版本之前的那个版本