Go编程语言到底有什么用?
了解谷歌热门编程语言的优势、劣势、用例和未来方向
谷歌的Go语言(又称Golang)在其十几年的发展过程中,已经从一个阿尔法极客的好奇心,发展成为世界上一些最重要的以云计算为中心的项目背后的经过战斗考验的编程语言--截止到2022年3月,其版本为1.18。
为什么Go被Docker和Kubernetes等项目的开发者选中?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函数、c组和命名空间对接,以发挥容器的魔力。
Go被广泛支持
Go工具链以Linux、MacOS、Windows二进制文件或Docker容器的形式免费提供。Go被默认包含在许多流行的Linux发行版中,如Red Hat Enterprise Linux和Fedora,这使得在这些平台上部署Go源代码变得更加容易。许多第三方开发环境对Go的支持也很强大,从微软的Visual Studio Code到ActiveState的Komodo IDE。
Go语言的最佳应用
没有哪种语言适合每项工作,但有些语言比其他语言适合更多工作。
Go语言在开发以下应用类型时最为耀眼。
云原生开发
Go的并发和网络功能,以及它的高度可移植性,使它非常适合于构建云原生应用程序。事实上,Go 被用来构建云原生计算的几个基石,包括Docker、Kubernetes 和Istio。
分布式网络服务
网络应用因并发而生,因并发而死,Go 的原生并发功能--主要是goroutines和channel--非常适合此类工作。因此,许多 Go 项目都是针对网络、分布式功能和云服务的。API、网络服务器、网络应用的最小框架等等。
实用程序和独立的工具
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的软件文化,如桌面应用程序中的GUI,仍然是分散的。
大多数 Go 应用程序是命令行工具或网络服务。尽管如此,各种项目都在努力为 Go 应用程序提供丰富的图形用户界面。有GTK和GTK3框架的绑定。另一个项目旨在提供平台原生的用户界面,尽管这些依赖于C语言的绑定,而不是用纯Go语言编写。而Windows用户可以尝试使用walk。但是在这个领域还没有出现明显的赢家或安全的长期赌注,一些项目,比如谷歌试图建立一个跨平台的GUI库,已经被淘汰了。另外,由于Go在设计上是独立于平台的,所以这些项目都不太可能成为标准包的一部分。
尽管Go可以与本地系统函数对话,但它并不是为创建低级系统组件而设计的,如内核或设备驱动,或嵌入式系统。毕竟,Go的运行时间和Go应用程序的垃圾收集器都依赖于底层操作系统。(对这种工作的尖端语言感兴趣的开发者可以关注 Rust语言)。
Go语言的未来
Go的未来发展正在更多地转向其开发者群体的愿望和需求,Go的指导者正在改变语言以更好地适应这些受众,而不是以顽固的例子来引导。一个典型的例子是泛型,在对最佳方式进行反复讨论后,终于将泛型添加到语言中。
2021年的Go开发者调查发现,Go用户总体上对该语言所提供的功能感到满意,但也提到了大量的改进空间。Go用户希望改进的首要领域是依赖性管理(Go的一个持续挑战)、诊断错误和可靠性,而诸如内存、CPU使用率、二进制大小和构建时间等问题则排名靠后。
大多数语言都倾向于一组核心的用例。在Go出现的十年中,它的利基已经变成了网络服务,在那里它可能会继续扩大其影响力。总的来说,该语言的主要用例是创建API或RPC服务(49%),其次是数据处理(10%),网络服务(10%),以及CLI应用(8%)。
Go语言的吸引力越来越大的另一个标志是许多开发者在评估后选择了它。在那些考虑在项目中使用Go的受访者中,75%的人选择了这种语言。在没有选择Go的人中,Rust(25%)、Python(17%)和Java(12%)是最主要的选择。这些语言中的每一种都已经或正在寻找其他的利基。Rust用于安全和快速的系统编程;Python用于原型设计、自动化和胶水代码;而Java用于长期的企业应用。
Go的速度和开发的简单性会使它在其他使用案例中走多远,或者Go会在企业开发中渗透多深,这些都还有待观察。但是Go作为一种主要的编程语言的未来已经得到了保证--当然是在云中,Go的速度和简单性使可扩展的基础设施的开发更容易得到长期的维护。