标签 Java 下的文章

2023年的Rust与Go[译]

本文永久链接 – https://tonybai.com/2023/02/22/rust-vs-go-in-2023

本文译自《Rust vs Go in 2023》

注:从2022年下半年开始,我们研发团队的产品研发不再局限于云端,车端也是将来的一个重要方向。于是我除了继续对Go语言保持常规的高度关注之外,也逐步开始留意Rust语言的发展。


Rust和Go哪个更好?Go还是Rust?在2023年,你应该为你的下一个项目选择哪种语言,为什么?两者在性能、简单性、安全性、功能、规模和并发性等方面如何比较?它们的共同点是什么,它们有哪些根本性的不同?让我们在这个友好而公平的Rust和Go的比较中找到答案。

Rust和Go都很棒

首先,我必须要说的是,Go和Rust都是绝对优秀的编程语言。它们都是现代的、强大的、被广泛采用的编程语言,并且都提供出色的性能。

你可能读过一些说Go比Rust好的文章,或者相反。但这真的没有意义;每一种编程语言都代表了一系列的权衡和取舍。每种语言都有自己的优化重点,所以你对语言的选择应该由适合你的东西和你想用它解决的问题决定。

在这篇文章中,我将尝试告诉你何时使用Go是理想选择以及何时使用Rust更佳。我也会试着介绍一下这两种语言的本质(如果你愿意的话,就是Go和Rust的道)。

虽然它们在语法和风格上有很大不同,但Rust和Go都是构建软件的一流工具。接下来,让我们仔细看看这两种语言。

Go和Rust的相似之处

Rust和Go有很多共同点,这也是你经常听到它们一起被提及的原因之一。两种语言的共同目标是什么呢?

Rust是一种低级静态类型的多范式编程语言,专注于安全和性能。 – Gints Dreimanis

Go是一种开源的编程语言,可以轻松构建简单、可靠、高效的软件。 – go.dev

内存安全

Go和Rust都属于现代编程语言,它们的首要任务是内存安全。经过几十年对C和C++等旧语言的使用,我们可以清楚地看到,导致错误和安全漏洞的最大原因之一是不安全地或不正确地访问内存。

Rust和Go以不同的方式处理这个问题,但它们的目标都是在管理内存方面比其他语言更聪明、更安全,并帮助你写出正确高性能的程序。

快速、紧凑的可执行文件

Go和Rust都是编译型语言,这意味着你的程序被直接翻译成可执行的机器码,因此你可以以单一二进制文件形式来部署你的程序;与Python和Ruby等解释型语言不同,你不需要将解释器和大量的库和依赖关系与你的程序一起分发,这是一个很大的优点。这也使得Rust和Go的程序与解释型语言相比都非常快。

通用语言

Rust和Go都是强大的、可扩展的通用编程语言,你可以用它们来开发各种现代软件,从网络应用到分布式微服务,或者从嵌入式微控制器到移动应用程序。

两者都有优秀的标准库、繁荣的第三方生态系统以及巨大的商业支持和庞大的用户基础。它们都已经存在了很多年,并将在未来几年内继续被广泛使用。今天学习Go或Rust将是对你时间和精力的合理投资。

务实的编程风格

Go和Rust都不是以函数式编程为主的语言(例如像Scala或Elixir),也不是完全面向对象的语言(像Java和C#)。相反,虽然Go和Rust都有与函数式和面向对象编程相关的特性,但它们是务实的语言,旨在以最合适的方式解决问题,而不是强迫你采用特定的做事方式。

如果你喜欢函数式编程风格,你会在Rust中发现更多对这种风格的支持,因为Rust在语法特性数量上要比Go更多。

我们可以讨论什么是“面向对象”语言,但可以说C++、Java或C#用户所期望的面向对象编程风格在Go或Rust中都不存在。 – Jack Mott

规模化的开发

Rust和Go都有一些有用的特性,使它们适合于大规模的编程,不管是指大型团队,还是大型代码库,或者两者兼具。

例如,C语言的程序员们多年来一直在争论将括号放在哪里,以及代码应该用制表符还是空格缩进,而Rust和Go通过使用标准的格式化工具(Go为gofmt,Rust为rustfmt)使用规范的风格自动重写你的代码,完全消除了这些问题。

这并不是说这种特殊的风格本身有多好:而是Rust和Go的程序员都喜欢这种标准化

gofmt的风格是没有人喜欢的,但gofmt却是所有人的最爱。 – Rob Pike

两种语言的另一个高分领域是构建管道(pipeline)。两种语言都有优秀的、内置的、高性能的标准构建和依赖管理工具;不再需要与复杂的第三方构建系统搏斗,也不再需要每隔几年就学习一个新的系统。

对于早期职业生涯以Java和Ruby为背景的我而言,构建Go和Rust代码感觉就像从我的肩上卸下了一个不可能的重担。当我在谷歌工作时,遇到用Go编写的服务是一种解脱,因为我知道它很容易构建和运行。Rust也是如此,尽管我只在较小规模的Rust项目上工作过。我希望可无限配置的构建系统的时代已经过去了,所有语言都会有自己专门的构建工具,开箱即可使用。- 山姆-罗斯

Rust还是Go?

综上可知,这两种语言都设计得很好、很强大,那么你可能会想知道那些关于两门语言的“圣战”究竟是怎么回事(我也是)。为什么人们对“Go vs.Rust”如此大惊小怪,在社交媒体上大打出手,并且写长篇博文说只有傻瓜才会使用Rust,或者Go不是真正的编程语言,或者其他什么。

这可能会让他们感觉好些,但这并不能完全帮助你,因为你正试图决定在你的项目中使用哪种语言,或者你应该学习哪种语言来推动你的编程生涯。一个明智的人不会根据谁喊得声最大来做出重要的选择。

现在让我们继续我们成熟的讨论,看看在某些领域,一个有理智的人可能更喜欢哪一种语言。

Go与Rust的性能对比

我们已经说过,Go和Rust都能生产出高性能的程序,因为它们被编译成了本地机器代码,而不必通过解释器或虚拟机。

然而,Rust的性能尤其突出。它可以与C和C++相媲美,这两种语言通常被认为是性能最高的编译语言,但与这些老语言不同的是,Rust还提供了内存安全和并发安全,并且基本上不会给执行速度上带去没有任何开销。Rust还允许你创建复杂的抽象,而不需要在运行时付出任何性能上的代价。

相比之下,尽管Go程序的性能也非常好,但Go主要是为开发速度(包括编译)而设计的,而不是执行速度。Go程序员更倾向于清晰的代码而不是快速的代码

Go编译器也不会花很多时间去尝试生成最有效的机器代码;它更关心的是快速编译大量代码。所以Rust通常会在运行时基准测试中击败Go。

Rust的运行时性能也是一致和可预测的,因为它不使用垃圾收集。Go的垃圾收集器非常高效,并且经过优化,使其“STW(停止世界)”的停顿时间尽可能短(每一个新的Go版本都会越来越短)。但是垃圾收集不可避免地在程序的行为方式中引入了一些不可预测的因素,这在某些应用中可能是一个严重的问题,例如嵌入式系统。

因为Rust旨在让程序员完全控制底层硬件,所以有可能将Rust程序优化到相当接近机器的最大理论性能。这使得Rust在执行速度胜过所有其他考虑因素的领域是一个很好的选择,比如游戏编程、操作系统内核、网络浏览器组件和实时控制系统。

简单性

如果没有人能够弄清楚如何使用一种编程语言,那么这种语言有多快也无所谓。Go语言是为了应对C++等语言不断增长的复杂性而特意设计的;它的语法非常少,关键字也非常少,事实上,功能特性也很少。

这意味着学习Go语言不需要很长时间,就可以用它来编写有用的程序。

Go是非常容易学习的。我知道这是一个经常被吹捧的好处,但我真的很惊讶于我能够如此迅速地提高工作效率。多亏了这个语言、文档和工具,我在两天后就写出了有趣的、可提交的代码。 – 一个Rust程序员对Go的早期印象

这里的关键词是简单性。当然,简单并不等同于容易,但是小而简单的语言比大而复杂的语言更容易学习。Go语言没有提供那么多不同的方法来做一件事情,所以所有写得好的Go代码往往看起来都一样。快速学习一个不熟悉的服务并理解它在做什么很容易。

fmt.Println("Gopher's Diner Breakfast Menu")
for dish, price := range menu {
    fmt.Println(dish, price)
}

在我的代码俱乐部视频系列中,我正是这样做的:从GitHub上半随机地挑选Go项目,并与一群Go初学者一起探索它们,看看我们能理解多少的代码。结果总是比我们预期的要多。

虽然核心语言很小,但Go的标准库却非常强大。这意味着你的学习曲线也需要包括你需要的标准库的部分,而不仅仅是Go语法。

另一方面,将功能从语言中转移到标准库中,意味着你可以只专注于学习与你现在相关的库。

Go也是为大规模的软件开发而设计的,支持有大型代码库的大型团队。在这种情况下,新的开发人员能够尽快上手是非常重要的。出于这个原因,Go社区十分看重:简单、明显、常规、直接的程序

使用Go,你可以快速完成工作。Go是我所使用过的生产力最高的语言之一。它的口号是:今天解决实际问题。 – 马蒂亚斯-恩德勒

特性

Rust比其他几种编程语言支持更多的复杂语法特性,因此,你可以用它实现更多。 – devathon

Rust是专门设计用来帮助程序员用最少的代码做最多的事情,它包括很多强大而有用的功能特性。例如,Rust的match功能可以让你以十分简洁地方式写出灵活的、富有表现力的逻辑:

fn is_prime(n: u64) -> bool {
    match n {
        0...1 => false,
        _ => !(2..n).any(|d| n % d == 0),
    }
}

因为Rust做了很多事情,这意味着有很多东西需要学习,特别是在开始的时候。但这没关系:在C++或Java中也有很多东西要学,而且你不会得到Rust的高级特性,比如内存安全。

批评Rust是一种复杂的语言忽略了一点:它被设计成具有表现力,这意味着有很多功能,而在许多情况下,这正是你想要的编程语言。

当然,Rust有一个学习曲线,但一旦你开始使用它,你就会好起来。

对于那些准备接受更复杂的语法和语义(以及可能更高的可读性成本)以换取最大可能的性能的程序员来说,Rust将与C++和D语言争夺思想份额。 – 戴夫-切尼

虽然Rust采用了Go的一些特性,而Go也在采用Rust的一些特性(尤其是泛型),但可以说Rust的特性很重,而Go的特性相对较轻。

并发

大多数语言都对并发编程(同时做多件事情)有某种形式的支持,但Go从一开始就是为这项工作而设计的。Go不使用操作系统的线程,而是提供了一个轻量级的替代方案:goroutine

每个goroutine是一个独立执行的Go函数,Go调度器会将其映射到其控制下的一个操作系统线程中。这意味着调度器可以非常有效地管理大量并发的goroutine,只使用有限的操作系统线程。

因此,你可以在一个程序中运行数百万个并发的goroutine,而不会产生严重的性能问题。这使得Go成为高规模并发应用程序的完美选择,如网络服务器和微服务。

Go还具有快速、安全、高效的功能特性,可以使用channel让goroutines进行通信和共享数据。Go的并发支持感觉设计得很好,使用起来也很愉快。

一般来说,对并发程序进行推断是很难的,而且在任何语言中建立可靠、正确的并发程序都是一个挑战。但由于它从一开始就内置于语言中,而不是事后才想到的,Go中的并发编程是最简单、最完整的。

Go语言可以很容易地建立一个很好的多因素的应用程序,充分利用并发性,同时作为一组微服务进行部署。Rust也可以做这些事情,但可以说它更难。 在某些方面,Rust对防止与内存有关的安全漏洞的痴迷意味着程序员必须不遗余力地执行那些在其他语言(包括Go)中会更简单的任务。 – Sonya Koptyev

相比之下,Rust中的并发故事是非常新的,而且还在稳定中,但它正处于非常积极的开发中,所以请关注这个领域。例如,Rust的rayon库提供了一种非常优雅和轻量级的方式来将顺序计算转化为并行计算。

拥有goroutines和使用channel的轻量级语法真的很好。这真的显示了语法的力量,这些小细节使并发编程比其他语言感觉好得多 – 一个Rust程序员对Go的早期印象

虽然在Rust中实现并发程序可能不那么简单,但还是有可能的,而且这些程序可以利用Rust的安全保证。

一个很好的例子是标准库的Mutex类:在Go中,你可以忘记在访问某些东西之前获得一个Mutex锁,但Rust不会让你这样做。

Go专注于将并发性作为一个一等公民的概念。这并不是说你不能在Rust中找到Go的面向actor的并发性,但这是留给程序员的一个练习。 – Dave Cheney

安全

我们在前面看到,Go和Rust都以不同的方式来防止一大类与内存管理有关的常见编程错误。但是Rust尤其努力确保你不会做一些你不想做的不安全的事情。

Rust的编译器非常严格和学究派,它检查你使用的每个变量和你引用的每个内存地址。它避免了可能的数据竞争条件,并告知你未定义的行为。并发和内存安全问题在Rust的安全子集中根本不可能发生。 – 为什么是Rust?

这将使Rust编程成为与几乎所有其他语言不同的体验,而且一开始可能是一种挑战。但对很多人来说,这种辛苦是值得的。

对我来说,Rust的关键优势是一种感觉,即编译器是我的后盾,不会让它可能检测到的任何错误通过(说真的,有时感觉就像魔法一样)。 – Grzegorz Nosek

包括Go在内的许多语言都有帮助程序员避免错误的设施,但Rust将这一点提高到了一个新的水平,因此可能不正确的程序甚至不会被编译。

有了Rust,库程序员有很多工具来防止他/她的用户犯错。Rust让我们有能力说,我们拥有一块特定的数据;其他东西不可能声称拥有,所以我们知道没有其他东西能够修改它。我想不出以前有什么时候我被赋予过这么多工具来防止意外的误用。这是一种奇妙的感觉。 – 山姆-罗斯

“与借用检查器(borrow checker)斗争”是Rust程序员新手的常见综合症,但在大多数情况下,它所发现的问题是你的代码中真正的bug(或至少是潜在的bug)。它可能会迫使你从根本上重构你的程序,以避免遇到这些问题;而当正确性和可靠性是你的首要任务时,这是件好事。

一个不改变你编程方式的语言有什么意义呢?当你用其他语言工作时,Rust所教授的关于安全的课程也是有用的。

如果你选择了Rust,通常你需要该语言提供的保证:针对空指针和数据竞争的安全,可预测的运行时行为,以及对硬件的完全控制。如果你不需要这些功能,Rust可能是你下一个项目的糟糕选择。这是因为这些保证是有代价的:入门时间。你需要戒掉坏习惯,学习新概念。有可能的是,当你开始的时候,你会经常和借用检查器斗争。 – Matthias Endler

你觉得Rust的编程模型有多大的挑战性,可能取决于你以前有哪些其他语言的经验。Python或Ruby程序员可能会发现它的限制性;其他人会很高兴。

如果你是一个花了几周的时间来追寻内存安全漏洞的C/C++程序员,你会非常欣赏Rust。”与借用检查器斗争”变成了”编译器可以检测到这个?酷!” -Grzegorz Nosek

规模化

今天的服务器程序由数千万行代码组成,由数百甚至数千名程序员进行构建,而且每天都在更新。Go的设计和开发是为了使在这种环境中工作更有成效。Go的设计考虑包括严格的依赖性管理,随着系统的发展,软件架构的适应性,以及组件之间的健壮性。 – Rob Pike

当你一个人或在小团队中处理问题时,选择简单的语言还是功能丰富的语言是一个偏好的问题。但是当软件越来越大,越来越复杂,团队越来越大时,差异就开始显现出来了。

对于大型应用程序和分布式系统来说,执行速度不如开发速度重要:像Go这样刻意简化的语言可以减少新开发人员的启动时间,并使他们更容易处理大型代码库的工作。

有了Go,作为初级开发者更容易提高工作效率,而作为中级开发者则更难引入会导致后续问题的脆弱抽象。由于这些原因,Rust在企业软件开发方面不如Go有说服力。 – Loris Cro

当涉及到大型的软件开发时,清晰的比聪明的好。Go的局限性实际上使它比Rust等更复杂和强大的语言更适合企业和大机构。

Rust和Go的不同点

虽然Rust和Go都是流行的、现代的、广泛使用的语言,但它们并不是真正的竞争对手,因为它们故意针对的是完全不同的使用情况。

Go的整个编程方法与Rust的完全不同,每一种语言都适合一些人,同时也会刺激另一些人。这完全没问题,如果Rust和Go都能以或多或少相同的方式做同样的事情,我们就不会真的需要两种不同的语言。

那么,我们是否可以通过发现Rust和Go所采取的截然不同的方法来了解它们各自的本性呢?让我们拭目以待。

垃圾回收

“要不要垃圾回收”是一个没有正确答案的问题。垃圾回收,以及一般的自动内存管理,使得开发可靠、高效的程序变得快速和容易,对于一些人来说,这至关重要。

但也有人说,垃圾回收及其性能开销和停顿,使程序在运行时表现得不可预测,并引入了不可接受的延迟。争论还在继续。

Go是一种与Rust非常不同的语言。虽然两者都可以被模糊地描述为系统语言或C语言的替代品,但它们有不同的目标和应用、语言设计的风格以及优先级。垃圾回收是一个真正巨大的区别。Go中的GC使语言更简单,更小,更容易推理。在Rust中没有GC会让它变得非常快(尤其是当你需要保证延迟,而不仅仅是高吞吐量的时候),并且可以实现Go中不可能实现的功能和编程模式(或者至少是在不牺牲性能的情况下)。 – PingCAP

接近机器

计算机编程的历史是一个越来越复杂的抽象的故事,它让程序员在解决问题时不用太担心底层机器的实际运作。

这使得程序更容易编写,也许更容易移植。但是对于许多程序来说,对硬件的访问以及对程序执行方式的精确控制更为重要。

Rust的目标是让程序员“更接近机器”,有更多的控制权,但Go抽象了架构细节,让程序员更接近问题。

两种语言都有不同的适用范围。Go在编写微服务和典型的”DevOps”任务方面表现出色,但它不是一种系统编程语言。Rust对于那些看重并发性、安全性和性能的任务中更强;但它的学习曲线比Go更陡峭。 – Matthias Endler

必须运行更快

许多人同意,对于大多数程序来说,性能不如可读性重要。但当性能确实重要时,它真的很重要。Rust做了一些设计上的权衡,以达到尽可能好的执行速度。

相比之下,Go更关注简单性,它愿意为此牺牲一些(运行时)性能。但是Go的构建速度是无可匹敌的,这对于大型代码库来说是非常重要的。

Rust比Go快。在基准测试中,Rust更快,在某些情况下,甚至是数量级的快。但在你选择用Rust写所有东西之前,考虑一下Go在许多基准测试中并不落后于它,而且它仍然比Java、C#、JavaScript、Python等快得多。如果你需要的是顶级的性能,那么选择这两种语言中的任何一种,你都会在游戏中领先。如果你正在构建一个处理高负载的网络服务,你希望能够在纵向和横向上进行扩展,那么这两种语言都会非常适合你。- 安德鲁-拉德

正确性

另一方面,如果一个程序不需要正常工作的话,它可以任意地快。大多数代码不是为长期而写的,但有些程序能在生产中运行多长时间往往是令人惊讶的:在某些情况下,可以保持几十年。

在这种情况下,值得在开发中多花一点时间,以确保程序的正确性、可靠性,并在未来不需要大量的维护。

Go和Rust都旨在帮助你编写正确的程序,但方式不同。例如,Go提供了一个极好的内置测试框架,而Rust则专注于使用其借用检查器消除运行时的错误。

我认为。Go适用于明天必须交付的代码,而Rust适用于必须在未来五年内保持运行不动的代码。 – Grzegorz Nosek

虽然Go和Rust对于任何严肃的项目来说都是很好的选择,但是让自己尽可能地了解每种语言及其特点是一个好主意。

归根结底,别人怎么想并不重要:只有你能决定哪种语言适合你和你的团队。

如果你想加快开发速度,也许是因为你有许多不同的服务需要编写,或者你有一个庞大的开发团队,那么Go是你的首选语言。Go把并发性作为第一等公民给你,并且不容忍不安全的内存访问(Rust也是如此),但不强迫你管理每一个细节。Go是快速和强大的,但它避免了使开发者陷入困境,而是专注于简单性和统一性。如果在另一方面,拧出每一盎司的性能是必要的,那么Rust应该是你的选择。 – 安德鲁-拉德

结论

我希望这篇文章能让你相信Rust和Go都值得你认真考虑。如果可能的话,你应该争取在这两种语言中至少获得一定程度的经验,因为它们对你的任何技术职业都会有极大的帮助,甚至如果你仅把编程作为一种业余爱好的话。

如果你只有时间投资学习一门语言,在你将Go和Rust用于各种不同类型的大小程序之前,不要做出最终决定。

而编程语言的知识实际上只是成为一名成功的软件工程师的一小部分。到目前为止,你需要的最重要的技能是设计、工程、架构、沟通和协作。如果你在这些方面表现出色,无论你选择哪种语言,你都会成为一名优秀的软件工程师。学习愉快!


“Gopher部落”知识星球旨在打造一个精品Go学习和进阶社群!高品质首发Go技术文章,“三天”首发阅读权,每年两期Go语言发展现状分析,每天提前1小时阅读到新鲜的Gopher日报,网课、技术专栏、图书内容前瞻,六小时内必答保证等满足你关于Go语言生态的所有需求!2023年,Gopher部落将进一步聚焦于如何编写雅、地道、可读、可测试的Go代码,关注代码质量并深入理解Go核心技术,并继续加强与星友的互动。欢迎大家加入!

img{512x368}
img{512x368}

img{512x368}
img{512x368}

著名云主机服务厂商DigitalOcean发布最新的主机计划,入门级Droplet配置升级为:1 core CPU、1G内存、25G高速SSD,价格5$/月。有使用DigitalOcean需求的朋友,可以打开这个链接地址:https://m.do.co/c/bff6eed92687 开启你的DO主机之路。

Gopher Daily(Gopher每日新闻)归档仓库 – https://github.com/bigwhite/gopherdaily

我的联系方式:

  • 微博(暂不可用):https://weibo.com/bigwhite20xx
  • 微博2:https://weibo.com/u/6484441286
  • 博客:tonybai.com
  • github: https://github.com/bigwhite

商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。

2022年Go语言盘点:泛型落地,无趣很好,稳定为王

本文永久链接 – https://tonybai.com/2022/12/29/the-2022-review-of-go-programming-language

早早就计划好在年前写一个Go语言年度盘点,就像2020年2021年那样。但恰逢国内疫情管控放开,一波阳了之后身体十分容易疲劳,再加上工作上的事情挺多,这篇盘点也就迟迟没能下笔。

今年的盘点思路将围绕三个关键字来展开:泛型、无趣(boring)和稳定。下面我们逐一来看看。

1. “泛型”靴子落地

2022年3月中旬,Go社区尤其是那些期盼Go加入泛型特性的Gopher终于迎来了Go 1.18版本的正式发布,这意味着Go泛型这只靴子终于落地了

其实,从Go开源那一天开始,Go核心团队就没有间断过对泛型的探索,并一直尝试寻找一个理想的泛型设计方案,但始终未能如愿。直到近几年Go团队觉得Go已经逐渐成熟,是时候下决心解决Go社区主要关注的几个问题了,包括泛型、包依赖以及错误处理等。其中泛型常年在Go官方用户调查报告的“你最想要的Go语言特性”这项调查的榜单上霸榜,下图摘自2020年度Go官方用户调查结果:

之后,Go团队安排伊恩·泰勒和罗伯特·格瑞史莫花费更多精力在泛型的设计方案上,这才有了Go 1.18 版本中泛型语法特性的落地。

个人觉得:Go泛型是Go核心团队对Go社区的一次迎合与妥协,因为泛型与Go的主要设计哲学“简单”是有悖的。泛型这个语法特性会给语言带来复杂性,这种复杂性不仅体现在语法层面上引入了难于理解和使用的新的语法元素,也体现在类型系统和运行时层面上为支持泛型进行的复杂的实现。

如果从2010年6月份,伊恩·泰勒提出的Type Functions设计方案算起,到2022年3月份的泛型落地,Go加入泛型之路足足走了近12年。不过结果还是不错的,经过近12年的努力与不断地自我否定,Go团队终于找到了一个不违背Go1兼容性承诺(见下图)泛型实现方案

从这方面讲,Go对泛型的支持又是十分成功的。在如此语法巨变的情况下,依然保持向后兼容(backforward compatibility)。

不过如果你因为Go加入了对泛型的支持就打算投入Go阵营,这里先给你一些友情提示:和支持泛型的主流编程语言之间的泛型设计与实现存在差异一样,Go的泛型与其他主流编程语言的泛型也是不同的。在学习Go泛型之前,可以先了解一下Go泛型设计方案已经明确不支持的若干特性,比如:

  • 不支持泛型特化(specialization),即不支持编写一个泛型函数针对某个具体类型的特殊版本;
  • 不支持元编程(metaprogramming),即不支持编写在编译时执行的代码来生成在运行时执行的代码;
  • 不支持操作符方法(operator method),即只能用普通的方法(method)操作类型实例(比如:getIndex(k)),而不能将操作符视为方法并自定义其实现,比如一个容器类型的下标访问 c[k];
  • 不支持变长的类型参数(type parameters);
  • … …。

这些特性如今不支持,后续大概率也不会支持。所以小伙伴们,尤其是来自Java、C++等语言阵营的小伙伴,在进入Go泛型语法学习之前,你一定要先了解Go团队的这些设计决策。

此外,目前的Go泛型实现和最后一版的泛型设计方案相比还有差距,依旧不是完全版,还有一些特性没有加入,还有问题亟待解决

就目前笔者观察来看,Go泛型还处于早期阶段,远非成熟。Go module构建模式从go 1.11版本加入到go 1.16成为默认并逐渐成熟还花了3年多时间呢,何况是Go泛型。这样来看,初步预测Go泛型要到2025年才会成熟,而成熟的标志无非如下几个:

  • 泛型语法特性确定以及稳定下来;
  • 语法问题基本都解决;
  • Go标准库开始广泛使用泛型;
  • Go泛型的运行时性能问题得到基本解决。

目前Go团队对泛型的应用依旧保持谨慎,并在循序渐进地推进泛型在Go团队与Go社区的应用,最新的消息是Go团队已经提出proposal,计划在Go 1.21版本中将用泛型实现的maps包slices包加入Go标准库,这两个包原本计划在Go 1.18版本加入,但因Rob Pike的建议先放到了golang.org/x/exp下面待定。

2. 无趣(boring)很好

和其他主流编程语言如C++、Rust等在新版本中不断有新语言特性刺激程序员的神经,让大家阶段性产生兴奋感(exciting)不同,除了早期版本(比如Go 1.1和Go 1.2)以及里程碑的Go 1.5版本的完成自举和大幅降低GC延迟、Go 1.11版本的go module构建模式、Go 1.18版本的泛型落地之外,大部分版本的发布都很难让Gopher们十分兴奋,甚至业界都称“Go is boring(Go很无趣)”

在今年的线下GopherCon大会上,Go核心团队技术Leader Russ Cox发表名为“Compatibility: How Go Programs Keep Working”的主题演讲,在这个演讲中,Russ Cox借用了Go is boring的这一说法,并称That is good!

国外新冠管控放开早,经过几波疫情后,与病毒共存了,于是2022年的GopherCon大会又重新恢复线下举办。

Russ Cox的原话是:“boring is good. boring is stable. boring means to be able to focus on your work and not ours… We’ll keep doing everything we can to keep go boring for all of you”。

这几句英文不难,相信大家都能看懂。无趣的Go意味着稳定,意味着大家将注意力都集中在自己的工作上而不是Go核心团队身上(去关注新特性)。Go语言不会像其他编程语言那样堆砌新功能特性。

Russ Cox的这一观点代表了Go核心团队,也代表着Go演进未来演进的主基调。同时,Russ明确给出结论:不会有Go2了,Go 1.xy会一直持续下去。Russ甚至提出:兼容性才是Go最重要的feature

并且Russ Cox在Go项目的discussion中也给出保持Go兼容性的backward compatibilityforward compatibility的扩展方案与一个实例

关于“Go is boring”,Russ没有进一步展开说,记得之前译过一篇名为《Go语言很无聊…其实它妙不可言!》的文章,大家可以看看那篇文章进一步体会一下“Go is boring”的含义。

3. “稳定”是主旋律

Go的稳定不仅体现在Go语法特性的演化上,Go语言在各大语言排行榜上的排名也进入了相对稳定区,以TIOBE index为例,下面是2022年12月份的排名截图:

我查了一下《2021年Go语言盘点:厉兵秣马强技能,蓄势待发新征程》一文中2022年1月份Go的排名为13名,上图中2021年12月份是19名的数据应该是错误的,相对2021年12月份,Go实际排名上升1位。

我们看到2021年Go从14升到13,今年又从13升到12。按照TIOBE官方编辑说法,在新兴编程语言中,Go是唯一一个可能在未来冲入前十的后端编程语言。

Go语言在实际应用中的表现与上述排名的变化也十分契合,总体来说就是十分稳定,国内外都波澜不惊,国内大厂该用Go的也都用了,腾讯、字节依旧是这方面的领头羊,先后开源了不少Go实现的项目,最受瞩目的应该是字节将内部的Go框架逐一开源了,包括:netpollkitex(rpc框架)hertz(http框架)等。

为了更好的帮助大家回顾这一年来Go的稳定演化,这里简单整理了2022年Go大事件列表,供大家参考:

Go社区等待了多年的泛型语法特性终于加入Go中。

从调查结果中可以看到,Gopher对Go的满意度依然高达92%;81%的受访者对Go项目的长期方向充满信心。

这篇Go语言的综述文章由Russ Cox,Robert Griesemer,Rob Pike,Ian Lance Taylor和Ken Thompson联合撰写,是Go核心团队对10多年来Go演化发展的复盘,深入分析了那些对Go的成功最具决定性的设计哲学与决策,是Go诞生十多年来最重要的一篇文章。

该文介绍了ThreadSanitizer v2的工作原理,并总结了7类数据竞争模式。

相对于Go 1.18版本而言,Go 1.19是一个“小”版本,它主要针对Go 1.18版本中泛型实现的问题做了修改和优化,引入了Soft memory limit,更新了《Go内存模型》文档。

包括sync.Pool的优化、defer性能提升、基于系统信号的抢占式调度(go 1.14)、调度器性能提升、支持基于寄存器的调用规约、soft memory limit等。

软件供应链安全问题愈发受到各界关注。Go安全团队发布Go官方安全漏洞管理的工具和方案: govulncheck。govulncheck是Go安全漏洞数据库(Go vulnerability database)的一个前端,它通过Go官方维护的vuln仓库下面的vulncheck包对你仓库中的Go源码或编译 后的Go应用可执行二进制文件进行扫描,形成源码的调用图(callgraph)和调用栈(callstack)。

  • 2022年10月,GopherCon大会在芝加哥线下举行

Russ Cox发表《Compatibility: How Go Programs Keep Working》主题演讲,确定了未来Go语言演进的主基调。

  • 2022年11月,Go开源13岁生日

Go官方回顾了2022年Go团队的工作与成果,并简单说明了在新一年的工作,包括继续努力使Go成为用于大规模软件工程的最好的环境。计划特别关注供应链安全,提高兼容性和结构化日志记录(slog),当然还会有很多其他改进,包括profile-guided optimization等。

4. Go语言2023年展望

目前Go语言的演化与发展与我在2020年Go盘点中的预测基本一致。我现在依然坚持我的判断,即我在《Go语言第一课》专栏中所说的那样:

绝大多数主流编程语言将在其诞生后的第15至第20年间大步前进。按照这个编程语言的一般规律,已经迈过开源第13个年头的Go,很可能将进入自己的黄金5-10年。2022年泛型落地就是Go语言进入黄金5-10年的起点,待2025年泛型成熟后,Go将取得更快的发展速度。

前途是美好的,但道路的曲折坎坷的。目前Go更多应用于基础设施、中间件领域和基础微服务领域,在企业级业务系统方面,类似spring这样的“全家桶”框架的缺乏和无法达成一致,让开发者在开发复杂业务系统时依旧首选Java。期待Go在这方面能所有进展。

同时,Go演进道路上还存在另外一个风险,在我的《Go为什么能成功》一文中,我曾经提到过:“Go成也Google,败也Google”。Go团队目前的治理体系太过于依赖google,这是一门双刃剑。当google发展较好时,Go语言将从中受益。但当google开始走下坡路时,Go是否还能像如今这样风光呢?让我么拭目以待吧!


“Gopher部落”知识星球旨在打造一个精品Go学习和进阶社群!高品质首发Go技术文章,“三天”首发阅读权,每年两期Go语言发展现状分析,每天提前1小时阅读到新鲜的Gopher日报,网课、技术专栏、图书内容前瞻,六小时内必答保证等满足你关于Go语言生态的所有需求!2022年,Gopher部落全面改版,将持续分享Go语言与Go应用领域的知识、技巧与实践,并增加诸多互动形式。欢迎大家加入!

img{512x368}
img{512x368}

img{512x368}
img{512x368}

我爱发短信:企业级短信平台定制开发专家 https://tonybai.com/。smspush : 可部署在企业内部的定制化短信平台,三网覆盖,不惧大并发接入,可定制扩展; 短信内容你来定,不再受约束, 接口丰富,支持长短信,签名可选。2020年4月8日,中国三大电信运营商联合发布《5G消息白皮书》,51短信平台也会全新升级到“51商用消息平台”,全面支持5G RCS消息。

著名云主机服务厂商DigitalOcean发布最新的主机计划,入门级Droplet配置升级为:1 core CPU、1G内存、25G高速SSD,价格5$/月。有使用DigitalOcean需求的朋友,可以打开这个链接地址:https://m.do.co/c/bff6eed92687 开启你的DO主机之路。

Gopher Daily(Gopher每日新闻)归档仓库 – https://github.com/bigwhite/gopherdaily

我的联系方式:

  • 微博(暂不可用):https://weibo.com/bigwhite20xx
  • 微博2:https://weibo.com/u/6484441286
  • 博客:tonybai.com
  • github: https://github.com/bigwhite

商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言精进之路1 Go语言精进之路2 Go语言编程指南
商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats