0%

2024开源操作系统训练营第一阶段总结-wooeason

南京大学  吴奕胜

初见 Rust

训练营第一阶段的学习过程中,我初步掌握了一门新的编程语言 rust。这是我第一次接触到一门比较”新鲜”的编程语言,相较于课堂上学习的 C/C++,这无疑是一门更加现代也更加复杂的编程语言,拥有不少闻所未闻的新概念,新特性,当然,这也导致 rust 的学习并没有那么轻松。

余观夫 rust 之难,在”所有权”之义。入门阶段所以为惑者,所有权占十之八九。

我如何理解所有权?

C/C++ 中,一个变量名被映射到唯一一个内存中有实际含义的内容,反之不成立,我们可以使用指针很轻松地做到这一点。rust 所做的,正是保证这个”反之”的成立,将一块内容唯一对应于一个所有者,当所有者生命周期结束时,内存也被回收,这就保证了内存安全。

这样做的好处很明显,我们可以断言在满足所有权规则的前提下,内存的使用总是安全的;但是坏处也很明显,由于所有权机制的存在,不少在 C/C++ 中可以很简单地实现的数据结构或者函数,在 rust 可能需要费一番功夫。

把我们所学的 rust 的新特性做个分类,大致也就是两类:

  • 为了实现特定功能而实现的特性
  • 为了补充所有权机制的灵活性而存在的特性

这一点很好地体现在智能指针、unsafe rust 之类的概念里,虽然这可能造成很多麻烦,但长期来看终究是利大于弊,rust 严格得看起来有些偏执的编译器在教会我们,一个优秀的程序员应该在编程的过程中注意什么,不是吗?

令人耳目一新的枚举类型

初学 rust,其中的枚举类型让我赞叹不已。我之前只学习了 C/C++ 语言,并且实际上只是学习了 C 和部分的 C++C 中的枚举类型让程序员可以赋予某些值以现实的语义,但是并不好用。

在某个课程中,我们被要求实现一个游戏,游戏要求实现一个可以在地图中上下左右移动的人物,人物还需要可以执行诸如放炸弹之类的功能,部分动作可能有附带的属性。对于每一个动作,我们当然可以实现一个类,用以表示指令,但是这样做显然是不够简洁的,而用 rust 中的枚举功能,则可以优雅地实现。

再比如编译原理课程中,我们要实现类型检查,那么很自然的就是要实现一个结构体,用以表示各种类型。在这个结构体中,一个枚举类型用以表示当前类型,一个 union 中保存了该种类型附加的信息。即使使用到了 union 这样的关键字减少冗余的部分,也并不优雅,如果换成 rust,则可以用一个枚举类型实现类型系统,相当简洁明了,且优雅。

说到底,枚举类型好用还是其成员可以附带一些信息,这是一般的枚举做不到的,并且即使用结构体或类等实现了类似的功能,也远不如 rust 中枚举的实现优雅。

模式匹配——优雅版本的 switch

说模式匹配是优雅版本的 switch 其实也有失偏颇,毕竟模式匹配的功能要比后者多多了,但更多的时候(至少在入门学习阶段),主要的用法还是这两种:

  • 用于解构元组、枚举等等
  • 用于匹配特定的分支

先来说说 switch 让我感觉最不舒服的地方,就是每个分支后面需要加上一个 break,在编译原理课程实验中,对语法树进行语义分析的过程中,时常需要根据产生式的类型实现不同的功能,由于某些稀奇古怪的原因,在写代码的时候会漏掉 break,这会导致比漏掉 break 的原因还稀奇古怪的结果。

相比之下,rust 中的模式匹配就避免了这个问题,同时也让逻辑一致的情况可以使用 | 合并到同一个分支,相较于 switch 中省略 break 的写法,可以消除很多潜在的问题。

Option<T>Result<T, U>

在以往的编程经验中,我常常碰到需要表达”没有”的语义的情况,这时候可能会使用一个极大值或者 $0$ 等约定的值来表达。比如在我们在表示一个无权图中不存在的边时,可以使用 $0$ 来表示,但如果是一个有权图呢?根据我们要解决的问题不同,用 $0$ 或者极大值的情况都有,这就造成了一些潜在的麻烦。Option<T> 就很好地解决了这个问题。我知道,其实 C++ 中已经有类似的功能了,但是就使用方便程度来讲,模式匹配加上 Option<T> 可以称得上是一个大杀器了。

而错误处理也很自然地解决了需要调用者自行处理问题的情况。以往的编程经验中,遇到需要传递错误信息的情况往往是通过某些约定的值,这些值被假设不在函数返回值的域中,通过这些值来告诉调用者出现了什么问题。Result<T, U> 显然是更好的实现方法。

说到底,我们想要表达的”空”的语义和”幺元”的语义并不总是一致的,又或者在函数返回的域中并没有不会用到的值,这就导致了”空”的语义不好表达,这个情况下,带值的枚举真香。

我的收获

上面提到的内容,大体上就是所有 rust 给我带来最印象深刻的地方了,当然,rust 还有不少精心设计的语言特性,不过由于我的编程经验不够,并不能直接说出这些特性好在哪,也并没有被这些特性震撼到,不过,我心里也埋下了这样一颗种子,如果在将来的学习工作中遇到了什么问题,再回过头来看如今所学,或许就能有更深刻的理解了。

这是我第一次学习一门”课外语言”,这样的体验是很有价值的,不管是对我学习使用这门语言本身来说,还是对我更深入理解以前学习过的语言来说。前面所写的几节内容都是我在学习比较 rust 过程中的切身体会,比学习优秀的设计更重要的是,我知道了一个没那么优秀的设计不好在哪里。

无论怎样,第一阶段的学习落下帷幕,接下来需要进入第二阶段攻克更加困难的主题,这是十分激动人心的。祈祷中……