为何选择 Go 语言?
绪论
编程语言是用于产品开发的工具。开发者的能力并非简单由所使用的语言决定。然而,选择何种语言以及如何运用它,确实能直接影响开发者的思维方式和成长方向。特别是,超越当前使用的语言,与其他语言进行比较,对于拓宽技术视野和培养对事物本质的感知力大有裨益。本文将从五个方面阐述我选择Go的原因,以及Go在哪些方面有助于开发者的成长。
1. Go 是一种平衡性能与生产力的语言。
世上存在着无数种编程语言,每种语言都因其特性而各具优缺点。
- C 语言具备卓越的性能和低级控制能力,但开发者需要手动管理内存,且缺乏高级功能,导致生产力低下且维护困难。
- C++ 和 Rust 支持面向对象、模板、元编程等多种高级功能,但其语法复杂、学习曲线陡峭,且编译速度慢,不适合反复部署。
- Java 和 C# 提供平台独立性和稳定性,广泛应用于大型服务,但它们运行在笨重的虚拟机上,导致部署和运行环境复杂,资源需求也较高。
- Python 和 Javascript 因其简洁的语法和丰富的生态系统而适合快速开发,但其执行性能较差,生态系统的可靠性较低,在大规模系统中会暴露出结构性限制。
与此相反,Golang是一种在性能和生产力之间取得卓越平衡的语言。Go作为一种编译型语言,既能保证高执行性能,又能以快速的编译速度提供解释器级别的部署灵活性。换言之,Go是一种平衡的语言,在大多数环境中都能稳定地发挥作用,没有明显的缺点。
2. Go 阻止“货拜物编程”。
第二次世界大战期间,盟军为了支援战争,在太平洋岛屿上建立了空军基地。大量的补给品和军事装备支援极大地改变了士兵和原住民的生活。岛民们首次见到了飞机运载着制造好的衣服、罐头食品和其他物品。战争结束后,基地被废弃,货物不再抵达。于是,岛民们为了模仿士兵,打扮成空中交通管制员、士兵和水手,建造了类似跑道的地方,并用木棍向飞机发出着陆信号。他们继续进行游行,以期飞机能空投货物。然而,他们等待的飞机却从未到来。
“货拜物编程”是指在不理解代码或技术原理的情况下,仅仅模仿其表面形式的开发习惯。在现代开发者中,尤其是在Web开发领域,这种不理解含义却盲目模仿的习惯屡见不鲜。尽管React、Next、Spring、Django等框架使得开发者在不了解内部结构的情况下也能进行开发,但他们常常无法正确应对哪怕是一个小错误。加之最近AI代码生成工具的出现,复制粘贴结果而非亲自编写代码或理解原理的开发方式变得更加普遍。
Go从语言哲学的层面根本上规避了这些问题。Go并非以框架为中心,而是以标准库为中心设计的语言。开发者仅凭net/http、database/sql等基本库就能构建实际服务级别的Web服务器,从而自然而然地培养对网络、数据库、I/O等低级结构的直觉和理解。这种不依赖框架、从基本功开始扎实学习的结构,为开发者提供了持续成长、不偏离技术本质的基础。
3. Go 提供强大的并发模型。
现代CPU的发展方向不再是单纯提高单个核心的速度,而是通过并行利用多个核心来提升性能。因此,一个程序能够同时处理多项任务的并发性已成为必需,而能够高效设计和实现并发的语言的重要性也日益增加。 Go正是为这种环境优化的语言。goroutine是Go提供的轻量级线程,只需几KB的栈空间即可创建,即使同时运行数千个,也几乎不消耗系统资源。Go运行时通过其M:N调度器高效地将大量goroutine分配到OS线程上,这个过程无需开发者直接干预即可自动优化。通过这种方式,开发者无需复杂的同步逻辑或自定义调度,就能以安全且一致的方式设计并发逻辑。
此外,Go还积极支持利用mutex、waitGroup等同步工具以及channel、context进行现代并发设计。得益于这些结构,开发者无需拘泥于复杂的理论,就能自然而然地掌握并发和并行性的实际感受,并能够从无到有地达到可用的高水平抽象和设计能力。
4. Go 是由卓越的开发者们主导创建的语言。
Go是由Google以及Robert Griesemer、Rob Pike、Ken Thompson这些传奇开发者主导诞生的语言。特别是,他们是Unix和C语言的创始人,以及编译器和系统软件领域的巨匠,这本身就证明了Go的技术可靠性。此外,Go还融入了众多Google工程师的实战经验和大规模服务运营的专业知识,因此Go从一开始就致力于解决现实问题,并以一致的哲学和方向发展。
其他语言常常因兼容性断裂、设计变更、不稳定的许可协议、非标准化的生态系统而给社区和用户带来困扰。例如,Python因2和3的兼容性断裂而导致生态系统多年分裂;Java在被Oracle收购后,许可政策变得不稳定,导致企业不愿采用的案例增多。此外,Node.js至今仍存在CJS和ESM并存的情况,未能提供一致的模块系统。
相比之下,Go是一种将一致性和稳定性作为最高价值的语言。 Go团队严格维护向后兼容性,即使引入新功能,也坚持采用渐进式集成方式,以避免与现有代码冲突。其语法也避免了不必要的关键字,并通过限制过度抽象来防止语言本身变得过于复杂。此外,go fmt、go mod、go build、go test等一致的官方工具链确保所有Go项目都具有相同的开发环境和结构;强大且实用的标准库无需额外框架,即可充分支持Web服务器、文件处理、数据库连接等实际开发所需的大部分功能。