在超过 15 年的野蛮生长过程中,谷歌的 Go 编程语言从极少数极客的“小众爱好”发展成为一些全球最重要的云原生软件项目背后的经过实战检验的编程语言。

如果你曾好奇为何 Go 语言成为了诸如 Docker 和 Kubernetes 等项目的首选语言,那么这篇文章正是为你准备的。我们将探讨 Go 语言的独特特性以及它与其他编程语言的区别。你还将了解到 Go 语言适用于哪些类型的项目,包括用于人工智能工具的 Go 开发现状。最后,我们将概述 Go 语言的功能集、该语言的一些局限性以及它未来的发展方向。

Go 语言小巧且简单

Go 语言(通常被称为 Golang)是由谷歌员工开发的—主要由长期的 Unix 专家以及谷歌杰出工程师罗布·皮克主导—但它严格来说并非“谷歌项目”。相反,Go 是一个由社区开发的开源项目,由对 Go 的使用方式以及语言发展方向有明确见解的领导团队牵头负责。

Go 语言旨在易于学习且使用起来简单直接,其语法易于阅读和理解。Go 语言的功能并不繁多,尤其是与 C++ 等语言相比更是如此。Go 语言的语法类似于 C 语言,这使得长期使用 C 语言的开发者能够相对容易地学习它。不过,Go 语言的许多特性,尤其是其并发和函数式编程特性,又让人联想到像 Erlang 这样的语言。

作为一种用于构建和维护各类跨平台企业应用程序的类似 C 语言的编程语言,Go 与 Java 有很多共同之处。而且作为一种能够实现代码快速开发(这些代码可以在任何地方运行)的手段,你可以将 Go 与 Python 进行类比,尽管两者之间的差异多于相似之处。

Go 的文档将 Go 描述为“一种快速、静态类型、编译型的语言,但其使用起来却感觉像是动态类型、解释型的语言”。即使是大型的 Go 程序,也能在几秒钟内完成编译。此外,Go 还避免了 C 语言风格的包含文件和库所带来的大量开销。

Go 语言的优点

Go 语言是一种功能强大、使用便捷、运行速度快、可移植性强、具有互操作性并且拥有广泛支持的现代语言。这些特性使得它成为大型开发项目的首选。让我们更仔细地探讨一下 Go 语言的这些优点。

Go 具备多功能且使用便捷

Go 在满足许多常见编程需求方面的能力可与像 Python 这样的解释型语言相媲美。其中一些功能是语言本身所具备的,例如用于并发的 goroutine 和类似线程的行为,而其他功能则可在 Go 标准库包中找到,比如 http 包。与 Python 一样,Go 还提供了自动内存管理功能,包括垃圾回收。

然而,与解释型语言不同的是,Go 代码会被编译成运行速度极快的本地二进制文件。而且与 C 或 C++ 语言不同,Go 语言的编译速度极快——快到使用 Go 语言进行开发时,会让人感觉更像是在使用解释型语言而非编译型语言。此外,Go 的构建系统比其他编译型语言的构建系统要简单得多。构建和运行一个 Go 项目只需几个步骤,并且无需过多的记录工作。
Go 语言的运行速度比许多其他语言都要快。

Go 语言的二进制文件运行速度比其对应的 C 语言版本要慢,但对于大多数应用程序而言,这种速度上的差异几乎可以忽略不计。对于绝大多数工作而言,Go 语言的性能与 C 语言相当,而且通常比以开发速度著称的其他语言(包括 JavaScript、Python 和 Ruby)都要快得多。

Go 是可移植且可互操作的

使用 Go 工具链创建的可执行文件可以独立运行,无需默认的外部依赖项。Go 工具链适用于各种操作系统和硬件平台,并可用于跨平台编译二进制文件。此外,Go 以上所有功能都不会牺牲对底层系统的访问权限。Go 程序可以与外部 C 库进行交互或进行原生系统调用。例如,在 Docker 中,Go 与底层的 Linux 函数、cgroups 和命名空间进行交互,以实现容器的神奇功能。

Go 得到了广泛的支持
Go 工具链可作为 Linux、macOS 或 Windows 的二进制文件免费获取,也可作为 Docker 容器使用。Go 默认包含在许多流行的 Linux 发行版中,如红帽企业 Linux 和 Fedora,这使得将 Go 源代码部署到这些平台变得相对容易。在许多第三方开发环境中,对 Go 的支持也很强大,从微软的 Visual Studio Code 到 ActiveState 的 Komodo IDE 都是如此。

Go 语言的最佳应用场景

并非每种语言都适用于所有工作,但有些语言适用于的工作场景比其他语言更多。Go 在云原生开发项目、分布式网络服务以及开发实用工具和独立工具方面表现最为出色。让我们来探讨一下使 Go 在这些项目类型中特别适用的特性。

云原生开发

Go 语言的并发和网络特性以及其高度的可移植性使其非常适合构建云原生应用程序。事实上,Go 语言被用于构建云原生计算的几个重要基础,包括 Docker、Kubernetes 和 Istio。

分布式网络服务

网络应用程序的成败取决于并发性,而 Go 语言自带的并发特性——协程和通道——非常适合此类工作。因此,许多使用 Go 语言的项目都与网络、分布式功能和云服务相关。这些项目包括 API、网络服务器、适用于微服务的 Kubernetes 就绪框架等等。

实用程序和独立工具

Go 语言编译后的程序具有极小的外部依赖项,这使得它们非常适合用于创建实用程序和其他工具,因为它们启动速度快,并且可以轻松打包以便进行分发。其中一个例子是名为“Teleport”的访问服务器,它可以通过从源代码编译或下载预构建的二进制文件快速部署到服务器上。

Go 语言的局限性

现在让我们来探讨一下 Go 语言的一些局限性。首先,它缺少许多开发者可能需要的语言特性。此外,它将所有内容都打包进了可执行文件中,因此 Go 程序可能会很大。而且,Go 的垃圾回收机制实现了自动内存管理,但以牺牲绝对性能为代价。该语言还缺乏用于构建图形用户界面的标准工具包,并且不适合系统编程。

让我们详细探讨一下这些方面的问题。

Go 缺少了许多实用的语言特性

Go 那种固执己见的特性集既受到了赞誉也遭到了批评。Go 的设计倾向于小巧且易于理解,因此某些特性被特意省略了。结果是,在其他语言中常见的某些特性在 Go 中根本无法使用。这是有目的的,但对于某些类型的项目来说,这仍是一个缺点。

有一点 Go 缺少而其他语言所具备的便是宏功能,通常将其定义为在编译时生成程序代码的能力。C、C++以及(正在崛起的)Rust 都拥有宏系统。而 Go 没有宏功能,或者至少与这些语言的宏功能不同。Go 有的是一个工具命令“go generate”,它会在 Go 源代码中查找魔法注释并执行它们。这可以用于生成 Go 源代码,甚至运行其他命令,但其主要用途是通过编程方式生成代码,通常作为构建过程的前置步骤。

Go 语言长期以来一直存在的另一个问题,直到最近仍未得到解决,那就是缺乏通用函数。这种函数能够接受多种不同的变量类型。Go 语言的开发团队多年来一直拒绝在语言中添加这种通用函数,因为他们希望这种语法和行为能够与 Go 语言的其他部分相匹配。但自 2022 年初发布的 Go 1.18 版本起,该语言引入了通用函数的语法。由于 Go 生成器及其代码生成能力成为了一种可能的解决方案,以部分弥补通用函数的缺失,因此这种功能在 Go 中的使用已不再那么普遍。

事实是,Go 语言很少添加新的重要语言特性,而且通常也是在经过深思熟虑之后才会进行添加。这样做有助于保持不同版本之间的广泛兼容性,但代价是创新速度会变慢。

Go 的二进制文件体积较大

Go 的另一个潜在缺点是生成的二进制文件的大小。默认情况下,Go 的二进制文件是静态编译的,这意味着运行时所需的一切都包含在二进制图像中。这种方法简化了构建和部署过程,但以“Hello, world!”程序的大小约为 1.5MB 的 64 位 Windows 系统为例,代价就是其体积较大。Go 团队一直在每次发布版本时努力减小这些二进制文件的大小。还可以通过压缩或删除 Go 的调试信息来缩小 Go 二进制文件的大小。对于独立的分布式应用程序,这种方法可能比对于云或网络服务更有效,因为在云或网络服务中,如果有服务出现故障,拥有调试信息是有用的。

Go 的垃圾回收机制资源消耗大

Go 的另一个备受推崇的功能——自动内存管理,却可能被视为一个缺点,因为垃圾回收需要一定的处理开销。按照设计,Go 不提供手动内存管理,而且 Go 的垃圾回收机制因无法妥善处理企业应用中出现的各类内存负载而备受批评。

话虽如此,每一代 Go 语言似乎都在改进内存管理功能。例如,Go 1.8 使垃圾回收的延迟时间显著缩短,而 Go 1.25 引入了一个新的实验性垃圾回收器。虽然 Go 开发者可以在 C 扩展中或通过第三方手动内存管理库使用手动内存分配,但大多数人更倾向于使用原生解决方案。

Go 语言没有标准的图形用户界面工具包

大多数 Go 应用程序都是命令行工具或网络服务。不过,有多个项目正在努力为 Go 应用程序提供丰富的图形用户界面。有针对 GTK 和 GTK3 框架的绑定。还有一个项目旨在为不同平台提供原生用户界面,尽管它只专注于 Go 1.24 及以后版本。但在这个领域还没有明确的赢家或可靠的长期选择。此外,由于 Go 的设计是平台无关的,因此在这方面这样的项目不太可能成为标准包的一部分。

你不应该将 Go 语言用于系统编程

最后,尽管 Go 语言能够与底层系统功能进行交互,但它并非为开发诸如内核、设备驱动程序或嵌入式系统这类底层系统组件而设计。毕竟,Go 运行时和 Go 应用程序的垃圾回收器都依赖于底层操作系统。(对于此类工作的前沿语言感兴趣的开发者可能会考虑使用 Rust。)

Go 语言的未来

Go 语言的发展正愈发注重其开发者群体的需求和期望,其开发者团队对语言进行了调整,以更好地满足这些用户的需求,而非一味地以僵化的范例来引领发展。一个典型的例子就是泛型功能,它是在经过对如何实现这一功能的最佳方式的反复斟酌后才被纳入语言中的。

2024 年的“Go 开发者调查”结果显示,开发者总体上对 Go 语言感到满意。出现的问题主要是由于错误处理的冗长性、缺少或不成熟的框架以及使用 Go 的类型系统所致—这些方面都有待未来进一步发展。

与大多数语言一样,Go 语言随着时间的推移逐渐形成了其核心的使用场景,并在网络服务领域找到了自己的定位。未来,Go 语言很可能会继续扩大其在这方面的影响力。开发者调查中提到的其他应用场景包括创建 API 或 RPC 服务(74%的受访者),其次是命令行应用程序(63%)、网络服务(45%)、库/框架(44%)、自动化(39%)和数据处理(37%)。虽然只有 4%的受访者提到使用 Go 语言来开发人工智能技术,但那些使用它的人表示,Go 是在生产环境中运行人工智能驱动工作负载的强大平台。对于那些想用 Go 语言开发机器学习/人工智能的人来说,缺乏工具(23%)以及 Python 是此类工作的默认选择(16%)是主要原因。

目前尚不清楚 Go 语言在速度和开发简易性方面的发展会将它应用到哪些其他场景中,尤其是在那些由其他语言主导且已有大量使用案例的领域。Rust 适用于安全且高效的系统编程(这是 Go 语言不太可能涉足的领域);Python 仍然是机器学习/人工智能、原型设计、自动化和连接代码的常见默认选择;而 Java 仍然是企业应用程序的可靠选择。

但 Go 作为一种主流编程语言的未来已无可置疑—尤其是在云端,Go 的高效性和简洁性有助于简化可扩展的基础设施的开发,使其能够长期得到维护。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐