作者: 张汉东
前言
如果你学习 Rust 的过程感觉到艰难、痛苦或迷茫,不妨看一下这篇文章。 但如果你学 Rust 感觉很轻松,那这篇文章就对你无用,可以忽略。
虽然现在 Rust 学习资料非常丰富,但 Rust 是一门学习成本相对比较高的语言。面对不同语言经验的人,学习成本略有差别。
在学习 Rust 之前,需要了解你将会在 Rust 学习过程中付出什么样的心智成本。
零基础的人,需要补足一些必要的计算机科学相关的基础,以及建立对编程的理解。初学编程本身就是一项很大的挑战。
有一定编程基础的人,虽然对学习 Rust 有一定帮助,但还是会有一些阻碍。
- 只有 C 经验的人,学习 Rust 时,有如下挑战:
- Rust 编程范式。c 语言是过程式,而 Rust 是混合编程范式,支持面向对象和函数式编程风格。c语言过来的人,很容易把 Rust 写成过程式风格,虽然用过程式也可以用 Rust 写出完整功能,但在代码架构上会损失 Rust 的优势。和编程范式相关的概念:泛型/ trait / 错误处理 / 结构体 / 枚举 。
- 所有权和借用检查。c 里面是 手动管理内存,但是 Rust 是用所有权来管理。c 里面都是用指针,但是在 Rust 里,将指针进行了安全抽象变成了引用,需要有借用检查。 这些都是 c 开发者必须要掌握的概念。
- Unsafe Rust 安全抽象。c 语言开发者要理解 Unsafe Rust 的编码规范,理解如何进行安全抽象,这一点比较重要,尤其是和 C 相互调用时。
- 宏。 Rust 中声明宏类似于 C 语言的声明宏,都是代码替换,但是功能比 C 的强大,这些应该也算一个学习挑战。Rust 还有功能更强大的过程宏,可以在前期学习的时候不用考虑,后期再学。
-
有 Cpp 经验的人,默认其对 C 有一定了解,学习 Rust 时,有如下挑战:
- Rust 编程范式。 Rust 的混合范式 和 Cpp 的混合范式不同。Rust 不是纯粹的面向对象语言,没有构造函数。Rust 中的泛型、 trait 、枚举 和 错误处理 对于 Cpp 开发者同样是学习重点。
- 所有权和借用检查。因为 Rust 也引入了 和 Cpp 11 引入的 基于RAII 机制的智能指针,所以在内存管理方面,对 Cpp 11 及以上版本有经验的人更容易理解。但是没有这方面经验的 Cpp 开发者就有一定难度了。
- Unsafe Rust 安全抽象。这一点和来自 C 语言的初学者一样,是需要对 Unsafe Rust 的编码规范有一定理解。
- 泛型 和 过程宏。 Cpp 开发者有模版,但是 Rust 中有泛型。Rust 中泛型的功能没有 Cpp 模版强大,但是有过程宏可以弥补。也就是说 Cpp 模版编程 等价于 Rust 的泛型和过程宏的结合。如果 Cpp 开发者也想要在 Rust 中追求 模版编程的效果,那么需要掌握 泛型和过程宏。
-
只有 GC 语言使用经验的人,比如 Java、Python、Ruby 、Haskell等,学习 Rust 时面临的挑战和 Cpp 基本相同,但因为使用 GC 语言的人,大部分对底层内存管理没有足够深入的了解,入门曲线会更加陡峭。
所以, Rust 入门曲线陡峭与否,除了语言本身的复杂性之外,也跟每个人的编程基础有关。
Rust 认知框架介绍
认识到 Rust 学习曲线的根由之后,你会发现,你以往的编程知识其实无法平滑迁移到 Rust 语言的学习中。
所以,你需要一个通用的学习框架,按这个框架来给自己制定学习计划,来达到对抗这个学习曲线,并达成入门 Rust 并持续学习的目的。
这个学习框架其实很简单,只需要明白两点即可:
- 第一,不要急于求成,保持初学者心态,分阶段,分而治之。
- 第二,在每个阶段的学习过程中,不要仅有输入,更要保持输出。
说是学习框架,其实也是一种认知框架。接下来,我们来看具体操作。
分阶段学习
对于有一定编程基础的朋友,学习 Rust 要经历至少三个阶段:
- 整体学习一遍 Rust 语法。对 Rust 语法和语言特性有一个充分了解。
- Rust 基本所有权概念需要一定深入理解。
- 深入领域学习。上面两个阶段完成以后,就可以投入到领域实践中,进一步深入学习。
这三个阶段,面对不同经验的学习者,学习时间可长可短,因人而异。在学习过程中,可以搭配一些项目,由简入深。
要点就是,不要急于求成。
对于编程零基础的朋友,则在遵循上面三个阶段学习之前,需要补充一些必要的基础:
- 计算机科学基础,推荐一些快速入门的书籍:《计算机是如何工作的》、《程序是如何跑起来的》、《网络是如何连接的》
- 入门一下 C 语言。 入门 C 语言之后,学习 Rust 的时候有对比,更容易理解。
- 然后再遵循上面的三个阶段来学习 Rust 。
第一阶段:全面了解 Rust 语法
第一个阶段的学习,目标是全面了解 Rust 语法。
需要做到什么地步?
- 对 Rust 语法有一个比较全面的了解。
- 对 Rust 语法进行分类。
这个阶段不是让你一次性学会 Rust ,所以有些不理解的内容,也不要太钻牛角尖,允许自己暂时不理解,最好能记录一个问题清单。这个阶段的重点在于全面了解 Rust 语法,在头脑里构建出语法体系结构,其中分类是重点。要对语法进行分门别类梳理。比如数据类型、控制流程、结构体、trait和泛型、宏等等,它们分别的作用是什么。
第一阶段配套学习资料
- 《Rust 权威指南》,即 Rust 官方出品的 Rust Book 。
- 《Rust Cargo Book》
- 其他免费或收费的入门类 Rust 资料。
看这些资料学习的时候,要围绕第一阶段的学习目标:全面了解 Rust 语法。
对 Rust 语法有一个基本了解之后,可以通过官方出品的Rust by example 和 Rustlings 来检验自己的学习成果。
第一阶段练手项目推荐
第一阶段练手项目的选择存在一些误区,很多人喜欢用 Rust 来刷题来学习 Rust 。但其实刷题的效果并不好。
因为 Rust 所有权的限制,对于实现一些算法和数据结构,没有其他语言那么灵活自由。如果没有对 Rust 所有权有深入了解,那刷题遇到困难,比较容易放弃对 Rust 的学习,不容易坚持。
所以这个阶段比较推荐的项目,还是以做一些让自己容易产生成就感的项目比较好。总的原则就是:结合你自己的领域经验,选择简单的项目入手。
这里推荐一些练手项目:
- 结合官方的《Command Line Apps in Rust》一书,实现一个简单的终端应用,比如读取 CSV 文件之类。
- 去 GitHub 开源仓库中寻找案例灵感:
- 从 《Rust Magazine》 中寻找练手灵感。
- 其他,比如有些学习资料自身就配套应用案例。
第二阶段: 掌握 Rust 语言关键概念
达成第一阶段的学习目标之后,就可以开始第二阶段的学习了。
第二阶段的学习目标就是,掌握 Rust 语言的关键概念。主要包含如下概念:
- 所有权和借用检查。
- 类型系统与编程范式。
- Unsafe Rust 和 宏。
其中 「所有权和借用检查」是重点,只有在掌握了这两个概念之后,才算入门 Rust 语言。至于其他概念,可以在边做项目过程中逐渐掌握,但不能不知道它们。
第二阶段配套学习资料推荐
- 《Rust 编程之道》
- 《Programming Rust》第二版
- 《Rust Design Patterns》
- Rust 标准库文档
- 《Rust 编码规范》
- 《Too Many lists》
- 其他进阶类 Rust 书目,以及免费或收费的学习资料。
这里推荐的学习资料,不一定要全部都看完,可以着重去深入学习「所有权和借用检查」这部分重点。然后去了解 「类型系统与编程范式」、「宏」和「Unsafe Rust」等概念,也可以深入了解 Rust 设计模式相关概念。
之后,再花时间深入阅读一下 Rust 标准库文档,以及 学习 《Rust 编码规范》。
经过上面的学习,就能为投入 Rust 生产实践打下良好的基础。
第二阶段练手项目推荐
这个阶段比较推荐的项目,依然还是那个原则,即,结合你自己的领域经验,选择简单的项目,由简入深。与此同时,也可以开始阅读一些比较知名的优秀项目源码开始学习。
- 这个时候可以阅读 《Too Many Lists》来实现一个链表,或者,可以去 LeetCode 刷题,借此来检验自己对 Rust 所有权机制的理解。
- GitHub 项目中获取灵感:
第三阶段:深入领域学习
经过上面两个阶段的学习,学习者可以投入到自己的实际项目中开始学习了。如果没有自己的实际项目,可以参与到开源项目的贡献中去。
这个过程就是一个长期的学习和应用 Rust 的过程了。比如 Rust 并发和异步开发相关的内容,重点概念中关于类型系统、编程范式、宏、Unsafe Rust 的深入学习和应用,都在这个阶段去完成。
保持输入和输出
学习的过程,要保持输入和输出平衡。
什么叫输入? 从各种学习资源中汲取各种知识,叫输入。
输出的形式很多。写一篇文章、参与一个项目、做一次分享,都是输出。
只有输入和输出保持循环,人的大脑才会处于思考模式,你输入的东西才会沉淀为结构化记忆。
所以,在上述学习阶段,除了输入,还要让自己保持输出。这样你的精力和时间才不会白费。