南京大学 吴奕胜
初见 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
过程中的切身体会,比学习优秀的设计更重要的是,我知道了一个没那么优秀的设计不好在哪里。
无论怎样,第一阶段的学习落下帷幕,接下来需要进入第二阶段攻克更加困难的主题,这是十分激动人心的。祈祷中……