在开始这个项目前,我们对 Rust 的了解只停留在粗浅的“线程安全”、“没有数据竞争”等概念上。Rust 的学习也是在开发项目的过程中从零开始一点点进行的。Rust “学习成本高,学习曲线陡峭” 的特点在这个过程中我们都深有体会。但随着对语言的熟悉,后来我们也的确逐渐感觉到了一些 Rust 的好处。
-
所有 Rust 坏处中最大的一条就是学习曲线过于陡峭了。如同 vim 一般,虽然是编辑器之神,但想快速入门并非一件易事。在学习 javascript 时,我基本可以直接上手,看语法写代码;而对于 Rust 而言,这么做写出来的代码完全无法通过编译。因为从本质上来讲,Rust 甚至包含着一种新的从对数据的访问层面上有异于传统编程语言的编程思想。
-
所以在代码编写的过程中,与编译器作斗争成了 debug 的日常。我们写代码的状态基本是:写画 3 个小时,过编译再花 3 个小时,调 bug 再花三个小时。在写进程切换置换 Allocator 时,我们先后试了:
- 传实例对象(被所有权击倒)
- 传引用(被生命周期击倒)
- 传指针(static 要求线程安全而指针不满足)
最后无奈,使用“保存引用,传裸指针“的方式勉强满足了要求。
-
在 Allocator 的实现中,由于有类似于:分配空间,拿到空间的起始地址,转换为某种数据类型进行访问;或是需要用到 union 方式访问数据时,不得不使用裸指针进行操作,因此产生了大量的 unsafe block。并且语言本身对裸指针的限制多,操作不灵活(C 语言可以直接加加减减),在编写时造成了极大的麻烦。
-
在 Rust 中想实现一个全局变量比较复杂,但是使用十分简单,并且是线程安全的。在有了 ALLOCATOR、SCHEDULER、FILE_SYSTEM 这些全局变量后,在全局范围内进行相关操作都变得简单方便起来,并且有安全性保证。
-
对于所有权,由于 Rust 有着严格的限制,其可在编译期确定变量的生命周期,因此不会存在内存泄漏的问题。并且对于是否可变,编译器也有着严格的检查,降低了不经意间变量值被修改的危险。事实上,后期在我们 debug 的过程中,我一定程度上感受到代码的 bug 变少了。(当然也不排除是心理作用)
-
另外一个感受到的好处就是有一些很方便的智能指针,如:
- Box,可以在栈上开辟空间并指向它;
- Rc,引用计数指针;
- Arc,线程安全的引用计数指针;
我们的代码中大幅度使用了 Box。