前言

在我刚开始学习Rust的时候,在社区里听到最多的声音就是“Rust学习曲线陡”。已经有一定编程经验的人在学习一门新语言时,都喜欢直接上手写代码,因为这样可以快速体验这门语言的特色。对于大多数语言来说,这样确实可以达到一定的学习目的。但是当他们在初次学习Rust的时候,就很难通过直接上手来体验这种快感。

我第一次学习Rust时就遇到了这样的情况。我按以往的编程经验直接写下了代码,但是编译无法通过;可是有时候简单调换两行代码的顺序,程序就能顺利编译成功了,这让我非常困惑。我想这也是大多数人感觉“Rust学习曲线陡”的原因吧。经过和Rust编译器的多次“斗争”之后,我不得不重新反思自己的学习方法。看样子,Rust 编译器暗含了某种规则,只要程序员违反了这些规则,它就会检查出来并阻止你。这就意味着,作为程序员,你必须主动理解并遵守这些规则,编译器才能和你“化敌为友”。

所以,我就开始了对Rust的第二轮学习,忘掉自己以往的所学,抱着初学者的心态,从零开始系统地学习Rust。然而,事情并没有这么简单。

Rust官方虽然提供了Rust Book,但是内容的组织非常不友好,基本就是对知识点的罗列,系统性比较差。后来官方也意识到了这个问题,推出了第2版的Rust Book,内容组织方面改善了很多,对学习者也非常友好,但系统性还是差了点。后来又看了国内Rust社区组织群友们合著的Rust Primer,以及国外的Programming Rust,我才对Rust建立了基本的认知体系。

直到此时,我才意识到一个重要的问题:Rust学习曲线陡的根本原因在于Rust语言融合了多种语言特性和多种编程范式。这就意味着,Rust涉及的知识范围非常广泛,涵盖了面向对象、函数式、泛型、底层内存管理、类型系统、设计模式等知识。从底层到上层抽象,从模式到工程化健壮性,无所不包。可以说,Rust是编程语言发展至今的集大成者。对于大多数Rust语言的初学者来说,他掌握的知识体系范围是小于Rust所包含的知识量的,所以在学习Rust的过程中会遇到无法理解的内容。

我在学习Rust之前,所掌握的编程语言知识体系大多是和拥有GC的动态语言相关的,对于底层内存管理知之甚少。所以在我学习Rust所有权的时候,就很难理解这种机制对于内存安全的意义所在;而我所认识的一些拥有 C 语言编程经验的朋友,在学习 Rust 时面临的问题是,难以理解Rust支持的上层抽象,对他们来说,Rust中融合的类型系统和编程范式就是他们学习道路上的“拦路虎”;对于拥有 Haskell 等函数式编程经验的朋友,会感觉 Rust的类型系统很容易理解,但是底层的内存管理和所有权机制又成了需要克服的学习障碍;来自C++编程圈的朋友,尤其是懂现代C++的朋友,对Rust所有权机制理解起来几乎没有困难,但是类型系统和函数式编程范式可能会阻碍他们的学习。当然,如果正好你没有上述情况,那说明你的相关知识体系已经很全面了,你在Rust的学习之路上将会非常顺利。

这是不是意味着,在学习Rust之前需要把其他语言都学一遍呢?答案是否定的。

Rust编程语言虽然融合了很多其他语言的特性和范式,但它不是进行简单的内容堆叠,而是有机地融合了它们。也就是说,Rust遵循着高度的一致性内核来融合这些特性。我们只需要从Rust的设计哲学出发,牢牢地把握它的设计一致性,就可以把它的所有特性都串起来,从而达到掌握它的目的。这正是本书遵循的写作逻辑。

本书特点

从设计哲学出发,探索 Rust 语言的内在一致性。设计哲学是一门优秀编程语言保持语言一致性的关键所在。设计哲学是语言特性和语法要素设计的诱因和准则。理解Rust语言的设计哲学,有助于把握Rust语言的内核与一致性,把Rust看似纷繁复杂的特性都系统地串起来。

从源码分析入手,探索Rust地道的编程风格。Rust是一门自举的语言,也就是说,Rust语言由Rust自身实现。通过阅读Rust标准库和一些第三方库的源码,不仅可以深入理解Rust提供的数据类型和数据结构,更能体验和学习地道的Rust编程风格。

从工程角度着手,探索 Rust 对健壮性的支持。Rust 通过类型系统、断言、错误处理等机制保证内存安全的同时,还保证了系统的健壮性。从工程角度去看Rust,才能看到Rust对系统健壮性的支持是多么优雅。

从底层原理开始,探索Rust内存安全的本质。只有深入底层,才能理解Rust所有权机制对于内存安全的意义。而且可以进一步理解Rust的类型系统,以及Unsafe Rust存在的必要性。

读者群体

适合本书的读者群体包括:

· 有一定编程经验,想要学习Rust的初学者。

· 对Rust有一定了解,还想对Rust深入学习的进阶者。

本书不适合完全没有编程基础的人学习。

如何阅读本书

对于Rust初学者,建议按照章节顺序去阅读。因为本书每一章内容基本都依赖于前一章内容的前置知识。

对于Rust有一定了解的朋友,可以选择你感兴趣的章节去阅读。因为本书的每一章也是对一个垂直主题的深入探讨。

一些章节的开头罗列出了通用概念,这是为了更通透地讲解相关知识的来龙去脉。如果你对这部分内容不了解,那么建议你把这部分内容(属于前置知识)认真看完再去看后面的内容。如果你对这部分内容已经有了充分的了解,那么完全可以跳过,直接选择你最关心的内容去阅读。

章节概述

第1章 新时代的语言。这一章将从Rust语言的发展历史概述开始,引出Rust的设计哲学,通过设计哲学进一步阐述Rust的语言架构。该语言架构也是本书组织内容时遵循的准则之一。这一章还将介绍 Rust 语言社区的现状和未来展望。最重要的是,这一章将介绍 Rust代码的执行流程,这对于理解本书后面的章节会有所帮助。

第 2 章 语言精要。学习任何一门语言时,首先要做的就是了解其语法。这一章将罗列Rust语言中的常用语法,但不是简单罗列,而是遵循一定的逻辑进行罗列。在介绍语法之前,这一章会先对Rust语言的基本构成做整体概述。然后将介绍一个非常重要的概念:表达式。它是Rust语法遵循的最简单的准则之一。接下来才会依次介绍Rust中最常用的语法,让读者对Rust语言有一个初步的了解。

第 3 章 类型系统。类型系统是现代编程语言的重要支柱。这一章首先将以通用概念的形式介绍类型系统相关的概念,目的是帮助不了解类型系统的读者建立初步认知。接下来将从三方面阐述Rust的类型系统。为了理解Rust基于栈来管理资源的思想,有必要先了解Rust中对类型的分类,比如可确定大小类型、动态大小类型和零大小类型等。这一章还将介绍Rust类型推导功能及其不足。接下来将介绍Rust中的泛型编程。泛型是Rust类型系统中最重要的一个概念。最后会介绍Rust 的“灵魂”,trait 系统。对类型系统建立一定的认知,有利于学习后面的内容。

第 4 章 内存管理。这一章首先将介绍底层内存管理的通用概念。在此基础上,围绕内存安全这个核心,从变量定义到智能指针,逐渐阐述Rust中资源管理的哲学。这部分内容是真正理解Rust所有权机制的基础。

第 5 章 所有权系统。这一章首先会介绍关于值和引用语义的通用概念,然后在此基础上探讨Rust的所有权机制。读者将看到,Rust如何结合类型系统和底层内存管理机制,以及上层值和引用的语义形成现在的Rust所有权系统。然后,进一步围绕内存安全的核心,阐述借用检查和生命周期参数的意义。通过这一章的学习,读者将会对Rust的所有权系统有全面深入的了解。

第6章 函数、闭包和迭代器。在对Rust的类型系统和内存安全机制有了一定了解之后,我们将开始深入学习 Rust 编程最常用的语法结构。函数是 Rust 中最常用的语法单元。Rust的函数承载了诸多函数式编程范式的特性,比如高阶函数、参数模式匹配等,同时也承载了面向对象范式的特性,比如为结构体及其实例实现方法,实际上就是一个函数调用的语法糖。然后将介绍闭包的用法和特性,帮助读者对闭包建立全面深入的认知,更重要的是,通过学习闭包的实现原理,进一步了解Rust中零成本抽象的哲学思想。最后介绍迭代器模式,以及Rust中的迭代器实现机制。迭代器也是Rust最常用的特性,通过这一章的学习,你将彻底了解迭代器。

第7章 结构化编程。这一章将对Rust混合范式编程进行探讨,会重点介绍Rust中的结构体和枚举体,以及它们如何在日常编程中以面向对象风格编程。同时,还将介绍三种设计模式,前两种是Rust标准库以及第三方库常用的设计模式,最后是一种合理利用Rust资源管理哲学的设计模式。通过学习这一章的内容,有利于掌握地道的Rust编程风格。

第 8 章 字符串与集合类型。字符串是每门编程语言最基本的数据类型,Rust 自然也不例外。出于内存安全的考虑,Rust中的字符串被分为了多种,并且语言自身没有自带正则表达式引擎。这一章将从字符编码开始,围绕内存安全,对Rust中的字符和字符串做彻底梳理,并且阐述如何在没有正则表达式引擎的情况下,满足字符串进行匹配搜索等的需求。集合类型也是编程中必不可少的数据结构。这一章将着重介绍动态数组Vector和Key-Value映射集HashMap 的使用,而且还会深入挖掘 HashMap 底层的实现原理,介绍 Rust 标准库提供的HashMap安全性,进一步探讨如何用Rust实现一个生产级的数据结构。最后将通过探讨一个Rust安全漏洞的成因,来帮助读者正确理解容量的概念,从而写出更安全的代码。

第 9 章 构建健壮的程序。对于如何构建健壮的系统,Rust 给出了非常工程化的解决方案。Rust将系统中的异常分为了多个层次,分别给出了对应的处理手段。在这一章,读者将学习Rust是如何以分层的错误处理解决方案来帮助开发者构建健壮系统的。

第10章 模块化编程。现代编程语言的一大特色就是可以方便地进行模块化,这样有利于系统的设计、维护和协作。Rust在模块化编程方面做得很好。这一章首先将介绍Rust强大的包管理系统Cargo。然后会以真实的代码实例阐述Rust的模块系统,并且将包含Rust 2018版本中模块系统的重大改进。最后将以一个完整的项目为例阐述如何使用 Rust 开发自己的crate。

第11章 安全并发。Rust从两方面支持并发编程。首先,利用类型安全和内存安全的基础,解决了多线程并发安全中的痛点:数据竞争。Rust可以在编译时发现多线程并发代码中的安全问题。其次,Rust为了达成高性能服务器开发的目标,开始全面拥抱异步开发。这一章将从线程安全的通用概念开始,从Rust多线程并发讲到异步并发支持,带领读者逐步形成全面、深入、通透的理解。

第12章 元编程。元编程即程序生成程序的能力。Rust为开发者提供了多种元编程能力。这一章将从反射开始介绍Rust中的元编程。虽然Rust的反射功能没有动态语言的那么强大,但是Rust提供了强大的宏系统。这一章将从Rust的编译过程出发,带领读者深入理解Rust的宏系统的工作机制,并且以具体的实例帮助读者理解编写宏的技巧。从声明宏到过程宏,再到编译器插件,以及第三方库syn和quote最新版的配合使用,都将在本章进行阐述。

第13章 超越安全的边界。前面的章节内容基本都是建立在Safe Rust的基础上的。而这一章将主要围绕Unsafe Rust的内容来构建,主要分为4大部分。首先将介绍Unsafe Rust的基本语法和特性。然后,围绕基于Unsafe进行安全抽象的核心,阐述Unsafe Rust开发过程中可能引起未定义行为的地方,以及相应的解决方案。然后介绍 FFI,通过具体的实例来阐述Rust如何和其他语言交互,涉及C、C++、Ruby、Python、Node.js等语言,还将介绍相关的第三方库。最后,将介绍未来互联网的核心技术 WebAssembly,以及 Rust 如何开发WebAssembly和相关的工具链。

相信通过这13章的内容,读者将会对Rust有全面、深入和系统的认识。

勘误及更多资源

有人的地方就有Bug,此书当然也不例外。写书不仅是正确地传播知识和思想的途径,更是一种交流和沟通的方式。如果你发现本书中的任何错误、遗漏和解释不清楚的地方,欢迎提出反馈。

随书源码地址:https://github.com/ZhangHanDong/tao-of-rust-codes

勘误说明:

· 直接提交issues。

· 标明具体的页码、行数和错误信息。

· 积极提出勘误者将获得合金Rust勋章一枚。

更多的学习资源:

· 官方doc.rust-lang.org列出了很多学习文档和资源。

· 订阅Rust每日新闻[1],了解Rust社区生态发展,学习Rust。

致谢

首先,我要感谢Rust社区中每一位帮助过我的朋友,没有你们的奉献,就没有这本书。

感谢Mike组织社区编写的免费书籍Rust Primer。感谢Rust社区中不知名的翻译者翻译官方的Rust Book。感谢知乎《Rust编程》专栏作者辛苦的写作。感谢KiChjang、ELTON、CrLF0710、F001、Lingo、tennix、iovxw、wayslog、Xidorn、42、黑腹喵等其他社区里的朋友们,你们在我学习的过程中给予了我无私的帮助和解答,Rust社区有你们真好。感谢知道我写作并一直鼓励和支持我的朋友们。衷心希望Rust社区可以一直这么强大、温柔和友好。

然后,我要感谢电子工业出版社的刘恩惠编辑。感谢你给了我这个机会,让这本书从想法成为了现实。

最后,感谢我的妻子宋欣欣,因为她的温柔、大度、包容、信任和支持,才让我能够踏实且满含信心地做我自己想做的事。感谢我的父母,正是他们的培养,才使我具有积极、坚持不懈做事情的品格。

读者服务

轻松注册成为博文视点社区用户(www.broadview.com.cn),扫码直达本书页面。

· 下载资源:本书如提供示例代码及资源文件,均可在 下载资源 处下载。

· 提交勘误:您对书中内容的修改意见可在 提交勘误 处提交,若被采纳,将获赠博文视点社区积分(在您购买电子书时,积分可用来抵扣相应金额)。

· 交流互动:在页面下方 读者评论 处留下您的疑问或观点,与我们和其他读者一同学习交流。

页面入口:http://www.broadview.com.cn/35485


[1] https://github.com/RustStudy/rust_daily_news