最近做了一个知识库的产品开发,服务器端完全用 Rust 编写的。现在项目的核心功能已经完成,我来谈谈 Rust 的初步印象。
1. Rust 的开发效率
Rust 的入门门槛稍有些高。如果有 C/C++ 的经验,说实话,我觉得也不算太高。刚开始用的时候,会发现 Rust 没完没了地提示编译错误。在这个阶段,我发现自己很多不严谨的编程习惯。
幸运的是,这个过程很快就过去了。接下来,就会享受到 Rust 语言的高效率编程的乐趣了。目前,我觉得 Rust 是一个能够高效产出高质量代码的工具,让我有些爱不释手了!
接下来我聊一聊 Rust 给我印象最深的一些特点。
2. 优雅的错误处理
程序员都喜欢假设程序执行过程中不出现错误,一路下来把代码执行完。因此,对于中间过程可能出现的各种错误或多或少都会出现无视的情况。这无疑给程序埋下了一颗又一颗的定时炸弹。
C、C++、C#、Java 等语言都不遗余力地试图简化错误处理方法,但都不尽人意。Rust 给出了一种非常实用的方案,极大简化了错误的处理,让程序员能够集中精力去处理正常情况。
2.1 一个简单例子
Rust 利用自身强大的 enum 类型,定义了 Option 和 Result 类型(当然我们也可以根据需要自己定义),简化了函数返回结果的正确性检查。下面的代码从函数 fun
返回结果, Rust 用下面的语法形式取得合法的变量 x
,如果函数 fun
返回错误,则不做任何是事情。
if let Some(x) = fun(...) { /*...do something with x here...*/ }
换成 C 语言的话,等价的代码如下:
int err = fun(&x);
if (!err) { /*...do something with x here...*/ }
2.2 更复杂的情形
Rust 可以写出下面形式的代码:
fun1().and_then(|x|fun2(x)).and_then(|x|fun3(x));
换成 C 语言的话,简直就是噩梦:
err = fun1(&x);
if (err) return err;
err = fun2(x, &y);
if (err) return err;
err = fun(y, &z);
if (err) return err;
这里我们看到了闭包的应用,同时也看到了组合算子 and_then
在简化代码方面的魅力。除了 and_then 之外, Rust 还为 Option、Result 类型定义了一系列用途不一的组合算子,利用类似函数式编程的形式,简化程序设计。
2.3 巧用 ?号简化函数返回值
看一下 Rust 下面的函数代码:
fn fun(...) -> Option<MyType> {
...
other_fun_1(,,,)?;
other_fun_2(,,,)?;
...
other_fun_n(,,,)?;
...
}
如果换成 C 语言的话,代码如下:
int fun(MyType* data...) {
...
err = other_fun_1(...);
if (err) return err;
err = other_fun_2(...);
if (err) return err;
...
err = other_fun_n(...);
if (err) return err;
...
}
作为程序员,你敢保证每一个错误都会老老实实地处理吗?然而在 Rust 中,我们需要做的就是在可能出错的函数之后放置一个 ?号,这样当所调用的函数返回错误时,我们的函数自动终止,并把出现的错误原样返回给调用者。
Rust 还提供了很多其他机制,例如多变量匹配等,简化错误处理。正因为 Rust 能够毫不费力地把计算过程中的错误处理掉,所以,Rust 开发的软件才能够具备非常高的可靠性。 Rust 的出错处理机制为开发高质量软件奠定了坚实的基础。
3. 迭代器简化循环算法
利用闭包和 find 方法,轻松实现元素的查找:
if let Some(rule) = self.rules.iter().find(|x| &x.input.name == event) { /* dosomething here ! */}
利用迭代器 iter()
和函数 find()
,我们不需要 for
、while
、 loop
循环代码就可以实现其功能,大大简化了代码设计,也减少了出错的可能性。
我也是开始写出这样风格的代码,才对闭包的意义恍然大悟。其实,闭包就是我们定制的循环体代码,植入 find 的循环内部执行。闭包必须能够访问所在作用域的局部变量,使得 find 也能够根据这些局部变量的值进行计算。
我摘录几段我的项目中的真实代码,并用 C 和 C++ 同样功能的代码做个对比。
(要去做核算检查了,先写到这里,后续再写其他体会!)