七叶笔记 » golang编程 » 最理想的语言之一:GO为何如此与众不同?

最理想的语言之一:GO为何如此与众不同?

图源:morioh

编程语言 是程序员的主要工具,我们和这些抽象工具之间存在着某种密切的联系。

没错,本文又是一篇介绍广泛流行、新派而总体上很独特的编程语言——Go的文章。然而,为了像Go一样“简单、特别、有用”,我不会重述别人已经写过的东西。

我将尝试通过分析Golang的设计方案、背景与其鲜明的特点,以及今天它能如何有效运用来形成一个新的愿景。

Gopher外观

概述

先来看看下面这些论点:

· Go是不同的,但又很像。

· Go是独特的,但又没有特色。

· Go是年轻的,但却已经普及

· Go很小的,却又是强大的。

· Go简单,却又相当复杂。

· Go是独立运行的,却又是众多实例。

· Go是一种语言,但也是一种理念。

现在我们就来深入探讨一下这些观点。

创建背景

要想充分理解Golang的本质,需要深入了解其创建背景。由于当时的工具无法解决Google所面临的问题,Go就在强烈的变革需求中诞生了。

Golang的创建者Rob Pike说:“Go项目致力于解决Google软件开发缓慢和笨拙的问题,从而使该过程更高效和更具可扩展性。该语言是由编写、阅读、调试和维护大型软件系统的人所设计,这也是为他们自己所设计的。”

这就是说,设计Go时,有一系列特殊的问题要解决,最初拥有C、Pascal、Modula和Oberon等高级编程语言的最佳特性的坚实基础。它还牢记了Python、C++、 Java 等语言的有用特性,这些就是Go要解决的问题。

语言差异

然而,这绝不是要复制成功品,而是要想出新的解决方法来处理问题。有时候为了解决一个问题,需要放弃已经被证明无效的东西。而因此,Go的每一个特性大多源于主要约束,比如:

· 有刻意简化和清晰的语法,以达到可读、易学、易上手的目的。

· 有严格、安全、完全静态化的数据型语义,以便在编译时处理静态错误,加快执行和构建速度。

· 有一个垃圾收集器,虽然该垃圾收集器能有效处理内存不安全问题,保持合理的高执行速度和成熟的资源效率。

· 缺少共性和语法糖,以达到最小化、精确化、简单化的目的,因为仅有唯一解决特定问题的方法,只有一种使用风格,可明显加快开发、调试、审查和测试过程,使维护工作变得更加容易。

· 缺乏面向对象(OOP)的共同原则,如继承、类和普通接口,以解决OOP的批评,自从功能导向的语言兴起后,OOP的批评越来越多,虽然作为多范式语言的Go也是其中之一。另外,这也有助于实现正构性。

· 有 vendoring (从 1.11 开始被 Go Modules 所取代),这是一个强大的依赖管理系统,它的汇编器非常接近二进制代码,可实现快速构建,然后实现非常轻量级和二进制文件的大小效率。这使得它能与微服务架构模式以及一般的云原生开发完美匹配。

· 没有 try-catch异常处理。尽管饱受争议和诟病,但这其实是Golang处理错误的惯用方式,这实际上有很多好处:避免重复的错误处理代码,保持控制流的高效和执行速度,保持代码的干净和可读性,简化代码编写和调试。

可以看到,Go的开发者已经成功想出一套非常高效的语言约束系统,可实现其一些最大特点和功能。这种做法令人印象深刻,通过使用每一个约束条件,它成功地同时实现了多个主要特点。

应指出,我在这里定义的将Go的特性建立在其约束条件上的方法,并不完全是基于其创建者的名言、博客文章或演讲、语言的官方文件或其他作者的文章,其实这是我的个人理解和描述Golang的本质以及其独特性的方式。当然,你可以不同意我的观点,也希望你不要完全相信我说的话,要自己去研究。

而且在这一点上,Go与其他语言有很明显的不同,因为它们是通过添加新特性而共同进化的,从而增加了复杂性并变得越来越趋同,而Go则是先用一种方法来约束自己,然后大部分从一开始就保持了有限性。

“很多Go的新人都会要求从所知的语言中获取功能。但这些特性并不属于Go——而且语言是固定的。给Go添加功能不会让它变得更好,只是让它变得更大。这将使Go因少了点不同而变得不那么有趣。”

鲜明的特点

然而,这并不一定意味着Go存在缺陷或缺少重要的功能特性。事实上,这将使编程变得毫无用处,因为完全可以先用汇编语言,但Go并非如此。为了保持简单,Go非常刻意地避免在不解决问题的情况下增加复杂性的功能。

不必要的特性增加复杂性,却失去了清晰性。| 图源: Renee French

那么那些已经属于Go的功能呢?其实刻意简化的规则对他们来说也是很有作用的。Golang的创建者们做了一件令人难以置信的工作,他们创造了一个看似简单易用的东西,而它实际上是非常复杂的。

“Go其实很复杂。它是我所做过的最复杂的东西之一,但是它却让人觉得很简单……它需要大量的设计、思考、实现工作、完善。简单是隐藏复杂的艺术!”

让我们来看看Go中几个“简单”的东西:

· 垃圾回收器实际上是Go最简单的功能,因为它没有任何控制接口。但其实它也是最复杂的功能,因为它在提供完整的内存安全的同时,还能节省极高的运行速度,并提供惊人的资源效率。

无论如何,Go并不是最快的编程语言,Rust、Julia、C++和C会更快。但这些语言都没有GC,因此它们没有Go那么简单,其实也没有比Go快多少。不过在大多数情况下,这也是为了给下一个特别简单的功能做让步。

Concurrent gophers

Concurrency 又名Goroutines ,一般来说,Concurrency 模型是迄今为止最简单、最直接的实现方式。事实上,生成新的子进程的过程非常简单,只要输入go就可以了。

· 接口显然是Golang最鲜明、最具辨识度的特点之一。他们独特的设计方案独自解决了大部分OOP的诟病,实现了正交性和真正的组件架构,虽然只是一套毫无价值的方法,但仍然隐藏着一些巧妙的设计技巧。

· Packages可以不间断地工作,没有任何意外,而且使用感也很好,特别是导入东西的时候。使用go get工具,可以从任何地方进行:Gopkg,GitHub,GitLab,BitBucket,甚至是你自己的托管仓库源。但为了实现组件化、模块化、可扩展性、共享、数据隐藏和隔离等等,我猜它们背后也相当复杂。

· Go的Standardlibrary 中有一大堆非常方便的功能,这证明了Golang其实是一个功能相当丰富的语言。然而,这些功能的实现方式是它的独特之处。例如,使用import “net/http”, 通过一个完全具备生产能力的web服务器,可以立即在一个很棒的、高度并发的又极易使用的环境中实现上述所有特性。

· Reflection 并不像这个列表中的其他语言那样简单,因为它并不是所有编程语言中最直接的概念。不过Go仍然设法使大部分的内容,同时使它相对容易使用。

Reflection有时可以有意地避免,而采用Golang的另一种范式——代码生成,从Go的想法来说,Reflection没有那么神奇,但更加清晰高效。不过我个人认为它是“白魔法”,尽管效率较低,但Reflection其实有一些真正神奇的功能。

Golang的全部特性是深思熟虑解决另一个重大语言设计问题的结果,它要求在不增加整体语言复杂度的前提下,只选择合适的特性,并保持其清晰性。

简洁的架构是很难设计的,要构建起来也很复杂。但一旦弄好了,就很容易使用了。而Go成功做到了,也证明了这一点。

应用范围

现在已知Go有一些特性。它也很容易使用,速度快,生产力高。但它可以应用在哪里从而提高工作效率呢?到底能用Go来做什么?

经典的编程语言,比如C#和Java,在它们存在的过程中,几乎在所有的编程应用领域都能做到游刃有余,所以Go要与它们竞争似乎相当困难。确实是这样,但Go实际上并没有想要在所有编程应用领域发展,它是为特定的目的而设计的,所以从定义上来说,它不是通用语言。

然而,在现实中,它又像是通用语言。

尽管Google最初是为了满足他们的开发和环境需求而设计的,但当Go成为开源并迅速壮大其贡献者群体后,开发者显然希望将其用于更广泛的范围。随着Go 1的发布,这种语言被认为是一种通用语言。

但这并不是Golang通用化进程的目标。随着其社区规模越来越大,它正在扩大Golang的使用领域,并继续打造新的工具、包、框架、驱动、API、代码生成器,甚至更多厉害的东西,让新的开发者相信Go确实也可以成为他们的下一个主语言。

那么我们就来看看Go能干什么吧:

· 本地云web服务开发,特别是微服务的使用:Go kit、Micro、Gizmo、Kite、Goa、Caddy等等。

· 使用 Gin、Martini、Revel、Gorilla、Beego等开发REST API。

· 使用 gRPC、Twirp、Spiral、Gorilla开发RPC API。

· GraphQL API开发 graphql-go、gqlgen、thunder。

· 使用Serverless框架 Serverless Framework、Google Cloud Functions、Sparta、Gordon进行无服务器功能开发。

· 使用 Hugo、Vugu、TinyGo、Vecty进行Web UI开发(WebAssembly)。

· 使用 Gobot、Mainflux、TinyGo、EMBD进行机器人、物联网和嵌入式开发。

· 使用Cobra、cli开发CLI 应用程序。

· 使用 GoLearn、Gorgonia进行机器学习和AI开发。

还有一些不是特别明显的例子:

· 使用 gomobile开发移动应用

· 使用 Lorca、Wails、Fyne开发桌面应用

· 使用 Ebiten、Pixel、G3N进行游戏开发

· 为Discord、Telegram、Slack、more开发聊天机器人

· Blockchain 区块链开发

目前Golang的应用范围显然更多的是面向云、网络和系统编程。但考虑到社区非常热情、主动且活跃,Go正在稳步地进入几乎所有其他IT应用领域。

图源:Google

最后几点想法

我用Go做项目已经快一年了,到目前为止我还是非常兴奋。使用Go的感觉非常棒,尤其是看到自己用它达到更高的效率水平时。

Go背后的想法是基于这样的认识:编码本身往往是整个开发中最不重要的部分。因此,Go的做法是约束自己不做无谓的表达,以保证所有后续流程的简单、清晰、高效,比如维护、审查、阅读、编辑,然后这些流程也会有助于编码。

总的来说,我认为Golang的开发者做了一个令人难以置信的设计和实现工作,因此,我们现在有了一个最方便且最具成本效益的语言。而且由于他们正在寻求提高开发和维护大型代码库的速度和效率的方法,Go最终成为了终极的生产力提升工具。

为了总结Golang的独特性精髓,并确定这门语言是否适合你,我想再一次引用创建者的话,从Go的想法中引出我的核心观点:“与大多数其他的语言不同,Go有一个基本的权衡,即:你想要什么,更有趣的语言,还是更容易运行和维护的语言?”

留言点赞关注

我们一起分享AI学习与发展的干货

如转载,请后台留言,遵守转载规范

相关文章