0%

总结与感悟

自去年在操作系统训练营首次接触rust以来,这是第二次系统地再次过了一遍rust的知识,这是我学习的第一门类函数式编程语言,对于基本的语法掌握的还算可以,但是许多复杂的部分让我学起来感到痛苦。

首先是类型系统,作为强类型语言,对类型的要求很苛刻,每次涉及到复杂类型都要和编译器搏斗,为了安全牺牲掉了一些便捷是可以理解的,但是复杂的类型系统绝对会让初学者红温,这种感受在我做到101题,链表合并的时候达到了顶峰:)

其次是迭代器,迭代器使用起来非常方便,但是理解他的用法是有一些困难的,并且有一些需要记忆的内容,要特别注意。

这次加了十道算法题,感觉这种设计非常好,帮助我把前面的一些知识综合了起来,希望rust生态、os社区越来越好。

背景

在加入此次训练营之前,我正在学习MIT的xv6操作系统(RV汇编,C语言),一直听闻清华的用Rust写的OS–rCore–,而且也是基于xv6,RV版的。本打算结束了xv6再了解的,但是恰巧发现了春夏季训练营的报名机会而且时间也算合适,觉得如果想了解Rust和rCore就不要再拖延了,于是下定决心报名并开始正式地学习Rust语言。

心得

早已听闻Rust在内存安全方面全面的保护,以及Rust学习曲线之陡峭,在正式开始前就给自己做足了心理建设。

我并没有过严格的C/C++编程体验,在CS61C短暂的接触过C语言,在CMU-15445短暂的接触过C++,所以可能我并无法感受到相比C/C++,Rust为编程者带来的“思想解放”。但是在MIT xv6学习过程中,我确实深刻地体会到C语言“天使与魔鬼”的含义,C语言让编程者随心所欲地调用系统资源,但是编程者就要为(潜在的、无数的、折磨人的)“segmentation fault”,“undefined behavior”们负责。

在Rust学习过程中,我也切身体会到了“编译器教我做人”的感觉,意识到这并不是一句玩笑话。初期面对一堆报错,我会苦恼一个编译器怎么这也管那也管,我就是想把这个值赋给这个变量,你信我就好了这没问题……但是我逐渐意识到Rust语言的安全性也正因此得以体现,它让程序编写的初期就足够安全,避免了许多运行时的bug,也许增加了编程者的心智负担,但是确实为程序的运行增添了值得这样负担的保障和性能。这更加深了我作为编程者的“责任感”:你要对自己写下的程序负责,而不是随意暴露问题。

但是我作为Rust初学者,必须承认仍然对它知之甚少。我仍然无法感觉到为什么Rust作为系统编程语言,这也许是因为我把能对硬件资源肆意调用的权力当作了“一门系统编程语言”的特点。至此我觉得应该要对系统编程、C语言、Rust语言都要重新进行思考。

心得的最后,我想这样简短概况一下这两个多星期的Rust入门带给我的感受:Rust是一门要用心学的语言,不是一门顺便就学了的语言,如果无法做到反复体会咂摸Rust的思想,几乎无法用Rust做任何事。

目标

希望在未来rCore阶段的学习中,加深对操作系统,xv6,Rust语言,C语言的理解,同时对RV汇编再熟悉一下,上一次接触RV汇编以及是7个多月前61C的project了。

学习途径

  1. 所有权
  2. 引用
  3. 智能指针的使用
  4. 多线程与异步
  5. 数据结构的实现

    110题中值得反复学习的题目

  6. exercises/iterators/iterators3.rs
  7. exercises/threads/threads3.rs
  8. exercises/smart_pointers
  9. exercises/macros/macros3
  10. exercises/conversions/from_into
  11. exercises/conversions/from_str
  12. exercises/conversions/try_from_into
    • try_from 和 try_into 的不同使用场景
  13. exercises/tests/test5
    • 修改指针地址值没看懂。。。。
  14. exercises/tests/test6
  15. exercises/tests/test6
    • 外部函数调用相关
  16. exercises/algorithm

    思考

    随着学习以及对应题目的深入,Rust 相较于其他语言的优势愈发明显,Rust 在实现了绝大多数通用语言的功能的前提下,提出了所有权、智能指针机制,在内存管理方面可以说是举世无双。
    通过严格的编译检查和最大限度的自定义编码给编程者最大的发挥空间和最稳定的发挥成果。

    反思

  • 学习过程中过于匆忙,没能整理笔记,把 Rust 语言知识成体系的建立起来
  • 题目导向学习,导致对Rust底层原理没有十分清楚

    总结

    非常感谢训练营全体老师的辛苦付出,将我们带入了 Rust 神奇的世界。也很荣幸能够和全国各地的同学们一起学习,对于这个过程,我是乐在其中的。最后希望我能够再接再厉,在之后的阶段中完善笔记,形成自己的知识体系,并且在工程能力上更上一层楼。

最大的感受就是rust的编译器、lint和配套工具链、社区内容太齐全、也太强了,虽然说语法学习有一定难度,但很大程度上被这些优势所弥补了,所以可以说是比较轻松的完成了第一阶段的语法学习。当然对于一些rust编译实现的细节理解确实还有待提升,rust-quiz我在不临时查文档的情况下能正确回答出来的没几个。

除了rust本身的工具链和社区文档外,给我最大帮助的是两个可以辅助调试rust的工具,rr和fireDBG,堪称rust学习的绝配之作。这两个工具可以可复现地记录rust执行的情况,为一些容易混淆的部分的学习带来了极大的帮助——主要指后面的算法学习,我个人的算法基础较为薄弱,在加上不熟悉的rust语法,没有这两个工具的帮助需要绕不少弯路。

另外,我很喜欢rust的宏,这是我觉得相当优雅而有趣的工具,只可惜我对于它不是很熟练,但依然感觉到它的上限很高,且与rust本身融合得很融洽。如果有余力的话,我希望能继续深入研究rust的宏。

最后是对于rust的总体感觉。我感觉在rust身上能看到很多以往学习过的编程语言的影子。基底的c/c++风格、以接口和结构来实现OOP的golang风格、模式匹配和匹配守卫的haskell风格……只能说既视感太强了。rust与其说是完全开创的语言,不如说是在借鉴了大量过往语言的设计基础上的集大成者。这一点到有点像c++,不过没有一些历史包袱,rust的设计可以轻装上阵,抓住精要。

前言

在大概一年之前周围就有同学开始学习 Rust,自己也有类似的打算,但是一直没有动手。这次借着 rcore-os 开源操作系统训练营的机会,终于开始了学习 Rust 的过程。

学习过程

由于平时的时间比较少,训练营的在线课我很少有时间跟着上,我的学习方式主要是阅读 Rust语言圣经,如果遇到没看到过的问题/知识点,我会去查阅 Rust文档

img

在前期我的计划是学完 Rust 圣经的一部分,然后完成 Rustling 对应部分的习题,但是由于 Rustling 规定了完成的顺序,我的学习过程就变成了以完成 Rustling 为主线,遇到不会的问题去学习 Rust 圣经的对应部分/查阅 Rust 文档。


我的 Rustling 完成过程大概如下:

  • 2024/4/8,加入 classroom
  • 2024/4/10,完成 intro, variables, functions,这些部分比较简单
  • 2024/4/16,完成 vecs, move_semantics, if, primitive_types,这里学习了 Vec 集合类型,以及 Rust 中很重要的所有权、引用的内容,并完成了对应的习题。虽然内容比较难,但是习题的难度并不是很难,因为题目给的引导比较多,导致这里对引用的学习并不是很透彻,后面会提到。
  • 2024/4/18,完成了 enum, structs,这个部分比较简单
  • 2024/4/23,完成了 errors (错误处理),generics (泛型), hashmaps, modules, strings, traits,这个阶段是以为 26 号要截止,不想拖队友的后腿,然后将完成 rustling 作为了主要的任务去做,进度快了很多;这个阶段的习题也不是很难,主要是学习一些标准库内容的使用
  • 2024/4/24,完成了 clippy (一个 debug 提示工具), conversions, iterators, macros, smart_pointers, threads, tests,这部分习题的难度还是比较大的,其中 smart_pointers 和 threads 部分我只是勉强做完了习题,其中使用的 as_mut(), Arc 等因为没有专门学习其实并不是很懂
  • 2024/4/26,用两天时间完成了 10 个数据结构/算法题目,在做前三题的时候觉得是有点吃力,算法、写代码都会,但是写出来之后过不了编译,各种迷茫,因为引用和智能指针没有学好,这里花了些时间去补课。后面的7题就比较顺利了,大概一中午就写完了。
  • 终于,吃到了螃蟹!

image-20240428151924444

总结

不可否定的是,通过这个阶段的练习,我基本掌握了 Rust 的使用。如果全职学习的话 (6-8h/day),我觉得大概一周的时间就可以完成,但由于我还有日常的工作,所以学习过程其实是比较赶的。

关于学习路线的建议:

  • 可以先阅读相关书籍(比如 Rust语言圣经,基础部分写的还是很好的)学习 Rust 的语言基础,并完成 Rustling 的基础部分;
  • 之后就应以完成 Rustling 为主线,遇到问题可以看对应部分 Readme 中提供的参考资料,也可以自己去搜索相应的知识进行学习,因为这部分 Rustling 和书籍中讲的内容已经不完全对应了,所以应以 Rustling 为主。

总结 Rust 语言的文章已经又许多了。我的眼界和能力有限,对于操作系统更是一窍不通,即便接触 Rust 语言的时间比许多这这三周才开始学习的人要久,却甚至也写不出同学们这样清晰的总结,故在此分享学习过程中我的一些想法。尽管只是一个菜鸟的瞎扯,也希望能给读到的你一些有价值的想法。

Read more »

第一阶段总结

第一次接触 Rust,之前使用的一直是 C/C++、Python,对于 Rust 基础语法来说掌握比较快速,但是遇到一些进阶的方法就开始有些困难了,感觉很大一部分问题还是因为 coding 的太少,光从 110 到训练题目来看,代码量还是不够多,容易导致语法学习了又忘记了,希望能够在第二阶段的学习当中,进一步学习 Rust,同时掌握一些 Rust 的最佳时间。

以前一直听说 Rust,都说写 Rust 是与编译器斗智斗勇,在体验过后,发现确实如此,一直致力于如何写出让编译器开心的代码,Rust 很有意思,OS 也很有意思,希望在接下来的学习中能够学习更多的知识

第一阶段完结!!!!

总结

花了一天的时间,通过 rustlings 的 110 道题目重新过了一遍 rust 相关的语法和细节,帮助我重新学习巩固了很多之前没有掌握的细节。特别是智能指针相关的部分,之前对于 Arc,Box,Cow 之类的掌握的都不是很细节。

再感概一句,rust 的编译器真是太好用了,很多语法上的问题编译器都可以给你正确的提示,如果再配合上 CoPilot 简直就是学习利器,大大提升了学习效率。

这次知道训练营的时间太迟了,导致我没有能从头开始跟着上课,想来是错过了很多学习的机会和细节,希望后面第二阶段可以全程 follow,完成所有的任务。

总结

学习前的初印象

其实在参加此次训练营之前,我已经浅浅接触了一下Rust;起初是因为旁人的安利,我开始简单了解Rust,发现其所有权机制似乎能解答很久以前我关于对象内存释放解决方案的一个不成熟的想法;随后又用Rust写了一个很简单的小工具,又发现它的奇妙之处在于:一旦通过了编译器的拷打之后,程序再拿去运行就几乎不会再报错了。在我看来,编码期早解决问题,要比运行期晚解决问题好多了!这就是训练营开始前,Rust给我的两点初印象。

学习后的印象和比较

在开始学习Rustlings后,我才发现对于Rust的了解我还是太少了——Rustlings的习题设计相当全面、有趣,在做题实践中学习要比只对着文档阅读生动得多;如果把写代码当做是添加一系列描述来使得程序不断具体化、直到能够实实在在运行起来、交付价值的过程,那么Rust就提供了相当丰富的机制,去极其精细地描述程序。尽管贴标签难免是一种以偏概全的行为,但我还是非常喜欢用一些词语给接触过的编程语言贴标签:C语言是经典悠远,Python是简练干净,Go是轻快简陋,Java是丰富啰嗦,C#是优雅如诗(这些全是我的刻板印象!但也是我真实的内心体验),那么Rust就是精细严谨。

Rustlings中一些地方的回顾

Rustlings中,有的语法点虽然之前已经略有耳闻,比如所有权机制,但运用起来还是时常碰壁,对这部分后续可能还是需要加深理解;有的语法点之前在其他语言里也有接触过,比如Optional;有的语法点给我耳目一新的感觉,比如错误处理机制,感觉写法上就相当漂亮。

展望

各大IT论坛上经久不息的争论之一大概就是“谁(PHP)是世界上最好的语言?”,曾经我也很着迷于这个问题;现在我更想搞清楚每种语言的最适合的场景;在学习了Rust之后,我想将来要在核心或是底层模块上多多锤炼自己的Rust水平,恰好这次的rCore实现就是一个非常好的训练机会~

总结

我作为常年 C++ 选手,第一次体验 Rust,说几个令我印象深刻的点。

模块与 cargo

cargo 无疑是 Rust 相比 C++ 最闪耀的点之一,C++ 既不便于源码分发又难以二进制分发的特点,令几乎所有 C++ 程序员苦不堪言。Rust 的模块机制消除了 C++ 的头文件与源文件的区别,使得模块的划分更加清晰,同时 cargo 的依赖管理使得项目的构建更加简单。

当然,它也付出了对应的代价,比如编译不再是无状态的,不方便类似于 ccache 的工具做缓存,不方便做分布式编译。

enum

熟悉 C++ 的程序员对构造 Sum type 并不陌生。Rust 直接引入了 enum 关键字,使得 Sum type 的定义更加简洁,同时也引入了 match 关键字,使得对 Sum type 的处理更加优雅。

Ownership

Rust 的所有权机制是 Rust 最大的特色之一,也是最令人头疼的地方。Rust 的所有权机制使得内存安全问题在编译期就能被发现,但也使得程序员需要花费更多的精力去思考内存的所有权问题。

无状态的 struct

Rust 有一个我非常欣赏的地方,就是 Rust 的结构体不需要一个构造函数。构造函数和看似是一个非常便利的特征,一个对象创建时我们就能保证它处于一个正确状态,实际上却令心智模型变得更为复杂。程序员假设一个对象总是处于正确的状态,总是具有正确的生命周期,这使得容器类的设计变得更加困难。