Preface?前言A language that doesn’t affect the way you think about programming is not worth knowing.——Alan PerlisRust简介Rust是一门新的编程语言。
我想,大部分读者看到本书,估计都会不约而同地想到同样的问题:现存的编程语言已经多得数不清了,再发明一种新的编程语言有何意义?难道现存的那么多编程语言还不够用吗,发明一种新的编程语言能解决什么新问题?俗话说,工欲善其事,必先利其器。在程序员平时最常用的工具排行榜中,编程语言当仁不让的是最重要的“器”。编程语言不仅是给程序设计者使用的工具,反过来,它也深刻地影响了设计者本身的思维方式和开发习惯。
卓越的编程语言,可以将优秀的设计、先进的思想、成功的经验,自然而然地融入其中,使更多的使用者开阔眼界、拓展思路,受益无穷。
A programming language is a tool that has profound influence on our thinking habits.——Edsger Dijkstra所以说关于这个问题,我认为,如果与现有的各种语言相比,新设计的语言有所进步、有所发展、有所创新,那么它的出现就很有意义。
最近这些年,的确涌现出了一大批编程语言,可以说是百花争艳、繁华似锦。但是在表面的繁荣之下,我们是否可以自满地说,编程语言的设计和发展已经基本成熟、趋于完美了呢?恐怕不尽然吧!
那些优秀的编程语言中,不少都有自己的“绝活”。有的性能非常高,有的表达力非常强,有的擅长组织大型程序,有的适合小巧的脚本,有的专注于并发,有的偏重于科学计算,等等,不一而足。即便如此,新兴的Rust语言面市后依旧展现出了它的独特魅力,矫矫不群,非常值得大家关注。
作为多年来鲜有的新一代系统编程语言,它的设计准则是“安全,并发,实用”。Rust的设计者是这样定位这门语言的:
Rust is a system’s programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety.安全是的,安全性很重要。Rust最重要的特点就是可以提供内存安全保证,而且没有额外的性能损失。
在传统的系统级编程语言(CC++)的开发过程中,经常出现因各种内存错误引起的崩溃或bug。比如空指针、野指针、内存泄漏、内存越界、段错误、数据竞争、迭代器失效等,血泪斑斑,数不胜数。这些问题不仅在教科书中被无数次提起,而且在实践中也极其常见。因此,各种高手辛苦地总结了大量的编程经验,许多代码检查和调试工具被开发出来,各种代码开发流程和规范被制定出来,无数人呕心沥血就是为了系统性地防止各类bug的出现。尽管如此,我们依然无法彻底解决这些问题。
教科书解决不了问题,因为教育不是强制性的;静态代码检查工具解决不了问题,因为传统的CC++对静态代码检查不友好,永远只能查出一部分问题;软件工程解决不了问题,因为规范依赖于执行者的素质,任何人都会犯错误。事后debug也不是办法,解决bug的代价更高。
鉴于手动内存管理非常容易出问题,因此先辈们发明了一种自动垃圾回收的机制(Garbage Collection),故而程序员在绝大多数情况下不用再操心内存释放的问题。新发明的绝大多数编程语言都使用了基于各种高级算法的自动垃圾回收机制,因为它确实方便,解放了程序员的大脑,使大家能更专注于业务逻辑的部分。但是到目前为止,不管使用哪种算法的GC系统,在性能上都要付出比较大的代价。要么需要较大的运行时占用较大内存,要么需要暂停整个程序,要么具备不确定性的时延。当然,在现实的许多业务场景中,这点开销是微不足道的,因此问题不大。可是如果在性能敏感的领域,这是完全不可接受的。
很遗憾,到目前为止,在系统级编程语言中,我们依然被各种内存安全问题所困扰。这些年来,许多新的语言特性被发明出来,许多优秀的编程范式被总结出来,许多高质量的代码库被开发出来。但是内存安全问题依然像一个幽灵一样,一直徘徊在众多程序员的头顶,无法摆脱。再多的努力,也只能减少它出现的机会,很难保证完整地解决掉这一类错误。
Rust对自己的定位是接近芯片硬件的系统级编程语言,因此,它不可能选择使用自动垃圾回收的机制来解决问题。事实证明,要想解决内存安全问题,小修小补是不够的,必须搞清楚导致内存错误的根本原因,从源头上解决。Rust就是为此而生的。Rust语言是可以保证内存安全的系统级编程语言。这是它的独特的优势。本书将用大量的篇幅详细介绍“内存安全”。
并发在计算机单核性能越来越接近瓶颈的今天,多核并行成了提高软件执行效率的发展趋势。一些编程语言已经开始从语言层面支持并发编程,把“并发”的概念植入到了编程语言的血液中。然而,在传统的系统级编程语言中,并行代码很容易出错,而且有些问题很难复现,难以发现和解决问题,debug的成本非常高。线程安全问题一直以来都是非常令人头痛的问题。
Rust当然也不会在这一重要领域落伍,它也非常好地支持了并发编程。更重要的是,在强大的内存安全特性的支持下,Rust一举解决了并发条件下的数据竞争(Data Race)问题。它从编译阶段就将数据竞争解决在了萌芽