Go介绍

159 阅读5分钟

Go 语言是由谷歌(Google)开发的一门编译型静态类型编程语言。其核心设计与工具开发团队的许多成员,都在编程语言研究领域拥有多年经验。

Go 语言具备诸多特性,其中有些是其独有的,有些则借鉴自其他编程语言,具体包括:

  • 内置并发支持

    • 协程(goroutines,即 “绿色线程”),且启动新协程的操作十分简便

    • 通道(channels,基于 CSP 模型)与 select 机制,用于实现协程间的同步

  • 容器类型 map(映射)与 slice(切片)均为 “一等公民”

  • 通过接口(interfaces)实现多态性

  • 通过接口实现值的封装(value boxing)与反射(reflection)功能

  • 支持指针

  • 支持函数闭包

  • 支持方法

  • 支持延迟函数调用

  • 支持类型嵌入

  • 支持类型推导

  • 具备内存安全性

  • 支持自动垃圾回收

  • 具备出色的跨平台兼容性

  • 支持自定义泛型(since Go 1.18).

  • 支持自定义迭代器(since Go 1.23).

除上述特性外,Go 语言的进一步亮点如下:

  • Go 语言的语法经过刻意设计,力求简洁、清晰,且与其他流行编程语言相近。这一特点让 Go 语言的学习门槛更低,上手更轻松。
  • Go 语言配套提供了一套完善的标准代码库,涵盖各类常用功能。其中大部分库均支持跨平台使用。
  • Go 语言还拥有活跃的社区,同时存在大量高质量的第三方 Go 语言库及项目可供导入和使用。

Go 语言开发者通常被称为 “Gopher”(直译为 “地鼠”,是 Go 语言的官方吉祥物名称)。

事实上,尽管 Go 是一门编译型静态类型编程语言,它却具备许多通常仅在动态脚本语言中才有的特性。要将这两类语言的特性融合到一门语言中并非易事,但 Go 做到了。换言之,Go 既拥有静态类型语言的严谨性,又具备动态脚本语言的灵活性。虽说这两者之间难免存在一些权衡取舍,但在 Go 语言中,这些取舍带来的影响远小于特性融合所带来的益处。

可读性是对 Go 语言设计影响深远的重要因素。对于一名 Gopher 而言,理解其他 Gopher 编写的 Go 代码并非难事。

目前,最流行的 Go 编译器由 Go 语言编写,且由 Go 设计团队维护。后续我们将其称为 “标准 Go 编译器”,或简称 “gc”(即 “Go compiler” 的缩写,并非指垃圾回收 “GC”)。Go 设计团队还维护着另一款 Go 编译器 ——gccgo。如今,gccgo 的使用率虽不及 gc,但它始终发挥着参考作用,且两款编译器均在持续积极开发中。截至目前,Go 团队的工作重点仍放在 gc 的改进上。

gc 包含在 Go 工具链(Go 团队维护的一套 Go 开发工具)中。Go 工具链 1.0 版本于 2012 年 3 月发布。Go 语言的版本与 Go 工具链的版本保持一致,每年会发布两个主要版本。

自 Go 1.0 发布以来,Go 语言的语法变化不大,但 Go 工具链中的工具(尤其是 gc)在各个个版本中已有诸多改进。例如,对于采用自动内存管理的语言而言,垃圾回收导致的明显延迟是常见的诟病。但从 Go 1.8 开始,gc 中并发垃圾回收实现的改进基本解决了这一延迟问题。

gc 支持跨平台编译。例如,我们可以在 Linux 系统上编译生成 Windows 可执行文件,反之亦然。

用 Go 语言编写的程序大多编译速度很快。编译时间是影响开发幸福感的一个重要因素,而较短的构建时间也是许多程序员喜欢用 Go 进行开发的原因之一。

Go 语言可执行文件的优势如下:

  • 内存占用小
  • 代码执行速度快(远快于动态脚本语言,但略慢于 C/C++)
  • 启动时间短(因此拥有出色的部署体验)

其他一些编译型语言(如 C/C++/Rust)或许也具备这三项优势(且相较于 Go,它们可能各有独特优势),但它们缺少 Go 语言的三个重要特性:

  • 编译速度快,带来愉悦的本地开发体验和较短的部署迭代周期
  • 灵活性高,可媲美动态语言
  • 内置并发编程支持

上述所有优势相结合,使得 Go 语言成为一门出色的编程语言,也是各类项目的理想选择,尤其适用于网络应用程序和系统工具的开发。

当然,Go 语言并非在所有方面都尽善尽美。其设计中存在一定的权衡取舍,也确实有一些不足之处。例如:

  • 目前 Go 语言不支持任意不可变值,这导致标准库中许多本不希望被修改的值只能声明为变量。对于部分 Go 程序而言,这是一个潜在的安全隐患。
  • 近期版本中复杂度增加且漏洞增多:Go 1.22 和 1.23 版本引入的新变化,给语言语义增添了意外的复杂度和隐式行为。此外,这些变化还引发了向后兼容性问题及漏洞,而相关变更的负责人似乎不愿解决这些问题。