在其十多年的发展历程中, Google 的Go 语言(又名Golanground)已经从极客的好奇心发展成为一些重要云中心项目背后久经考验的编程语言。
为什么Docker和Kubernetes等项目的开发者会选择 Go作为开发语言 ?Go 的特征优势是什么,它与其他编程语言有什么不同,最适合构建什么样的项目?在本文中,我们将探讨 Go 的功能集、最佳用例、语言的遗漏和限制,以及 Go 的发展方向。
Go 语言小而简单
Go,或者通常所说的 Golang,是由谷歌员工开发的——主要是长期的 Unix 大师和谷歌杰出工程师 Rob Pike——但严格来说,它并不是一个“谷歌项目”。相反,Go 是作为一个社区主导的开源项目开发的,由领导层带头,他们对 Go 的使用方式和语言的发展方向有强烈的看法。
Go 意味着易于学习、易于使用并且易于其他开发人员阅读。Go 没有大量的功能集,尤其是与 C++ 等语言相比。Go 的语法让人想起 C,这使得长期 C 开发人员学习起来相对容易。也就是说,Go 的许多特性,尤其是它的并发和函数式编程特性,都可以追溯到 Erlang 等语言。
作为一种用于构建和维护各种跨平台企业应用程序的类 C 语言,Go 与 Java 有很多共同之处。作为一种能够快速开发可能在任何地方运行的代码的方法,您可以在 Go 和 Python 之间进行比较,尽管差异远大于相似之处。
Go 语言适合每个人
Go 文档将 Go 描述为“一种快速、静态类型的编译语言,感觉就像是一种动态类型的解释语言。” 即使是大型 Go 程序也将在几秒钟内编译。此外,Go 避免了 C 样式包含文件和库的大部分开销。
Go 以多种方式使开发人员的生活变得轻松。
Go很方便
在满足许多常见编程需求的能力方面,Go 与 Python 等脚本语言进行了比较。其中一些功能内置在语言本身中,例如用于并发和线程类行为的“goroutines”,而 Go 标准库包中提供了其他功能,例如 Go 的 http 包。与 Python 一样,Go 提供了自动内存管理功能,包括垃圾收集。
与 Python 等脚本语言不同,Go 代码编译为快速运行的本机二进制文件。与 C 或 C++ 不同的是,Go 的编译速度非常快——足以让使用 Go 感觉更像是使用脚本语言而不是编译语言。此外,Go 构建系统没有其他编译语言那么复杂。构建和运行 Go 项目只需要几个步骤和很少的簿记。
Go运行很快
Go 二进制文件的运行速度比 C 对应的要慢,但对于大多数应用程序来说,速度上的差异可以忽略不计。对于绝大多数工作而言,Go 的性能与 C 一样好,并且通常比其他以开发速度着称的语言(例如 JavaScript、Python 和 Ruby)快得多。
Go 是便携式的
使用 Go 工具链创建的可执行文件可以独立存在,没有默认的外部依赖项。Go 工具链可用于各种操作系统和硬件平台,并可用于跨平台编译二进制文件。
Go 是可互操作的
Go 在不牺牲对底层系统的访问的情况下提供了上述所有功能。Go 程序可以与外部 C 库对话或进行本地系统调用。例如,在 Docker 中,Go 与低级 Linux 函数、cgroup 和命名空间接口,以发挥容器的魔力。
Go 得到广泛支持
Go 工具链可作为 Linux、MacOS 或 Windows 二进制文件或 Docker 容器免费提供。Go 默认包含在许多流行的 Linux 发行版中,例如 Red Hat Enterprise Linux 和 Fedora,这使得将 Go 源代码部署到这些平台变得更加容易。从 Microsoft Visual Studio Code 到 ActiveState 的 Komodo IDE,许多第三方开发环境对 Go 的支持也很强大。
Go 语言在哪里工作得最好
没有一种语言适合所有工作,但有些语言比其他语言适合更多的工作。
Go 最适合开发以下应用程序类型。
云原生开发
Go 的并发和网络特性以及高度的可移植性使其非常适合构建云原生应用程序。事实上,Go 曾被用于构建云原生计算的多个基石,包括Docker、Kubernetes和Istio。
分布式网络服务
网络应用程序的生死取决于并发,而 Go 的原生并发特性——主要是goroutine 和 通道——非常适合这种工作。因此,许多 Go 项目用于网络、分布式功能和云服务:API、Web 服务器、 Web 应用程序的最小框架等。
实用程序和独立工具
Go 程序编译成具有最少外部依赖的二进制文件。这使得它们非常适合创建实用程序和其他工具,因为它们可以快速启动并且可以很容易地打包以便重新分发。一个示例是 称为 Teleport 的访问服务器(用于 SSH 等)。Teleport 可以通过从源代码编译或下载预构建的二进制文件快速轻松地部署在服务器上。
Go 语言限制
Go 的自以为是的功能集既受到赞扬也受到批评。Go 的设计倾向于小而易于理解,故意省略了某些功能。结果是某些在其他语言中很常见的功能在 Go 中根本不可用——这是故意的。
一个长期存在的抱怨是缺乏通用函数,它允许函数接受许多不同类型的变量。多年来,Go 的开发团队一直反对在语言中添加泛型,理由是他们想要一种语法和一组行为来补充 Go 的其余部分。但从 2022 年初发布的 Go 1.18 开始,该语言现在包含泛型语法。要吸取的教训是,Go 很少添加主要功能,而且只有经过深思熟虑,才能更好地保持跨版本的广泛兼容性。
Go 的另一个潜在缺点是生成的二进制文件的大小。Go 二进制文件默认是静态编译的,这意味着运行时所需的一切都包含在二进制映像中。这种方法简化了构建和部署过程,但代价是简单的“你好,世界!” 在 64 位 Windows 上重约 1.5MB。Go 团队一直在 努力在 每个后续版本中减小这些二进制文件的大小。也可以 通过压缩 或 删除 Go 的调试信息来缩小 Go 二进制文件。最后一个选项对于独立的分布式应用程序可能比对于云或网络服务更有效,如果服务出现故障,则拥有调试信息很有用。
Go 的另一个被吹捧的特性,自动内存管理,可以被视为一个缺点,因为垃圾收集需要一定量的处理开销。按照设计,Go 不提供手动内存管理,Go 中的垃圾收集因无法很好地处理企业应用程序中出现的各种内存负载而受到批评。
也就是说,每个新版本的 Go 似乎都改进了内存管理功能。例如,Go 1.8显着缩短了垃圾收集的延迟时间。Go 开发人员确实有能力在 C 扩展中使用手动内存分配,或者通过 第三方手动内存管理库,但大多数 Go 开发人员更喜欢本地解决方案来解决这些问题。
围绕为 Go 应用程序(例如桌面应用程序中的那些)构建丰富的 GUI 的软件文化仍然是分散的。
大多数 Go 应用程序都是命令行工具或网络服务。也就是说,各种项目正在努力为 Go 应用程序带来丰富的 GUI。GTK 和 GTK3 框架有绑定 。另一个项目旨在提供 平台原生 UI,尽管这些依赖于 C 绑定并且不是用纯 Go 编写的。而Windows用户可以试试 walk。但是在这个领域还没有出现明确的赢家或安全的长期赌注,一些项目,比如谷歌试图建立一个 跨平台的 GUI 库,已经被搁置了。此外,由于 Go 在设计上是独立于平台的,因此这些都不太可能成为标准包集的一部分。
尽管 Go 可以与本机系统函数通信,但它并不是为创建低级系统组件而设计的,例如内核或设备驱动程序或嵌入式系统。毕竟,Go 应用程序的 Go 运行时和垃圾收集器依赖于底层操作系统。(对此类工作的尖端语言感兴趣的开发人员可能会研究Rust 语言。)
Go语言的局限
Go 的未来发展将更多地转向其开发者群体的需求,Go 的思想者会改变语言以更好地适应这些受众,而不是通过顽固的榜样来引领。一个典型的例子是泛型,在对最好的方法进行了深思熟虑之后,最终将其添加到语言中。
2021 年 Go 开发者调查发现 ,Go 用户总体上对该语言提供的功能感到满意,但也提到了很大的改进空间。Go 用户希望改进的主要领域是依赖管理(Go 中的一个持续挑战)、诊断错误和可靠性,而内存、CPU 使用率、二进制大小和构建时间等问题的排名要低得多。
大多数语言都倾向于一组核心用例。在围棋出现的十年里,它的利基市场已经变成了网络服务,它可能会继续扩大其占有率。总的来说,该语言引用的主要用例是创建 API 或 RPC 服务 (49%),其次是数据处理 (10%)、Web 服务 (10%) 和 CLI 应用程序 (8%)。
Go 语言越来越受欢迎的另一个标志是有多少开发人员在评估后选择了它。在考虑使用 Go 进行项目的受访者中,75% 的人选择了该语言。在没有选择 Go 的人中,Rust (25%)、Python (17%) 和 Java (12%) 是首选。这些语言中的每一种都已经或正在寻找其他利基:Rust 用于安全和快速的系统编程;用于原型设计、自动化和粘合代码的 Python ;和用于长期企业应用程序的Java 。
Go 的速度和开发简单性将在多大程度上将其带入其他用例,或者 Go 将在多大程度上渗透到企业开发中,还有待观察。但是 Go 作为主要编程语言的未来已经得到保证——当然在云中,Go 的速度和简单性简化了可长期维护的可扩展基础设施的开发。