序言:Rust语言简介
参与过C/C++大型项目的同学可能都经历过因为Null Pointer、Memory Leak等问题“被” 加班了不知道多少个晚上。别沮丧,你不是一个人,Mozilla Firefox的开发者们同样经历过这个问题。浏览器可以说是我们日常使用最为频繁的软件了,目前主流的浏览器主要 有Google Chrome、Internet Explorer、Mozilla Firefox。为了提升用户体验,Mozilla就已经启动了多线程渲染的计划。然而,面对大型的C/C++工程,Mozilla的开发者们也坚持不住了。此时,Rust进入了开发者的眼中,与C/C++ ABI 兼容、多编程范式支持、无GC及独特的所有权系统,使得Mozilla与Rust语言一拍即合,并迅速启动了 Mozilla 的下一代浏览器引擎项目:servo,到目前为止(2018年8 月),servo已经成为了除Rust编译器自身外,社区中最大的Rust项目。servo目前已经部 分应用在Firefox 57之后的版本中。
Rust语言的设计目标是安全、高效、并发以及实用性。Rust 从一定程度上解决了C++的以 下痛点:
- 容器/数组越界访问;
- 动态内存分配的泄露与double free问题;
- 难以对依赖进行管理;
其中前两点在C/C++项目中是最容易引发Bug以及安全问题的原因,依靠人来对这些问题进行检查往往不是最佳的解决方案。Rust通过其独特的所有权系统,简化这个所研究的对象,使得一些隐晦的问题在编译期间便暴露出来。任何事情都是有两面性的,由于严格的编译期检查以及工程实现上的取舍,Rust在一定程度上牺牲了编译速度以及灵活性,对“灵活性”的舍弃并不代表Rust语言的表现力下降,只是我们在编写Rust程序时,可能需要 改变一下以往的思路。
在Rust圈子中,有一句调侃:“C++是调试的时候想撞墙,而Rust是编译的时候想撞墙”。
接下来我们将通过一个简单的例子来建立Rust中所有权系统的一个基本印象。
核心概念:所有权系统
Rust 的所有权系统包括三个核心概念:所有权、借用以及生命周期。我们首先来通过一个 简单的例子来建立对所有权以及生命周期的直观概念。
#[derive(Debug)]
struct Foo;
fn main() {
let foo = Foo; // Note: Foo not implement Copy trait
let bar = foo;
println!("{:?}", bar);
// println!("{:?}", foo);
}
首先创建了一个Foo类型的变量foo,然后我们执行let bar = foo;,然后我们尝试 输出这两个变量的值,如果我们将第9行的注释去掉,程序将无法通过编译,这是因为在 Rust中,对于没有实现Copy trait的类型,如果我们将一个绑定赋给另一个绑定,默认 使用的是move语义,也即对于任意给定的资源,当且仅当有一个变量绑定与之对应。
想要进一步学习Rust的小哥哥小姐姐,可以参考Rust Learning