欢迎学习本教程!本教程将教你如何使用 Rust 编程语言。Rust 是一门强调安全、性能和并发性的系统编程语言。它为了达到这几个目的,甚至没有一个垃圾收集器。这也使 Rust 可以应用到其余语言作不到的地方:嵌入到其余语言,有指定空间和时间需求的程序,写底层代码(如设备驱动程序和操做系统)。针对当前的其余编程语言,Rust 作到了没有运行时(Runtime),没有数据竞争。 Rust 也致力于实现“零成本抽象”,尽管这些抽象给人的感受像一个高级的语言。即便是这样,Rust 仍然能够作到像一个低级的语言那样的精确控制。html
“Rust 编程语言”分为七个部分。本文的简介是第一个。在这以后:git
新手入门 - 设置您的电脑来进行 Rust 开发。github
学习 Rust - 经过小型项目学习 Rust 编程。编程
高效的 Rust - 学习编写优秀 Rust 代码的一些高级概念。安全
语法和语义 - Rust 的每一部分,分解成小块来说解。并发
每日 Rust - 还没有构建稳定的一些高端特性。编程语言
术语 - 本教程的相关参考科目。函数
学术研究 - 影响 Rust 的一些著做。性能
阅读本文以后,你会想了解“学习 Rust”或“语法和语义”,根据你的喜爱:若是你想尝试一个项目,能够学习 “学习 Rust”章节;或者若是你喜欢从小的部分开始,完全的学习了一个概念以后才移动到下一个概念,那么你能够学习“语法和语义”章节。丰富的交叉联合使这些部分链接到一块儿。学习
本教程的源文件能够在 Github 上找到: <github.com/rust-lang/rust/tree/master/src/doc/trpl>
Rust 是你可能会感兴趣的一门语言么?让咱们先来看看一些能展现其一些优点的小代码示例。
让 Rust 变得独特惟一的一个主要的概念是名称为“全部权”的概念。思考下面这个小例子:
fn main() { let mut x = vec!["Hello", "world"]; }
这个程序有一个变量绑定名称为 x。此绑定的值是一个 Vec,是咱们经过在标准库中定义的宏建立的一个'向量'。这个宏被称为 Vec,咱们利用!调用宏用。这遵循 Rust 的通常原则:作事情要明确。宏能够有效的作一些比函数调用更复杂的东西,因此他们外观上来看是不同的。这个符号!也有助于解析,使代码更容易编写,这也很重要。
咱们使用 mut 使 x 可变:默认状况下,Rust 中的绑定是不可变的。咱们将在后面的例子中改变此向量。
另外值得一提的是,在这里咱们不须要标注类型:Rust 是静态类型,咱们并不须要再明确标注类型。Rust 有类型推断,用以平衡强大的静态类型和冗长标注类型。
Rust 更倾向于堆栈分配而不是堆分配:x 被直接放置在堆栈中。然而,Vec 类型是在堆上分配的向量元素的空间。若是你不熟悉它们之间的区别,那么你如今能够先忽略它,或者你能够查看章节“堆栈和堆”,来了解详细了解。做为一个系统编程语言,Rust 赋予了你如何分配内存空间的能力,可是在咱们开始的阶段,这是并非一个大问题。
此前,咱们提到的“全部权”是铁锈的关键新概念。生锈的说法,X 被说成“本身”的载体。这意味着,当 x 超出范围,载体的存储器将被解除分配。这是由防锈编译肯定性完成,而不是经过一个机制,诸如垃圾收集器。换句话说,在防锈,你不叫喜欢的 malloc 函数和释放本身:编译静态判断,当你须要分配或释放内存,并插入这些调用自己。犯错是作人,但编译器永远不会忘记。
前面咱们所提到的,“全部权”是 Rust 中的一个很是重要的新概念。按照 Rust 的说法,x 被称为向量“全部”。这意味着当 x 超出范围,向量的内存将被销毁。这样作是由 Rust 的编译器所决定的,而不是经过一种机制(如垃圾收集器)所决定的。换句话说,在 Rust 中,你不须要本身调用函数,如 malloc 和 free yourself: 当你须要分配或释放的内存时,编译器会自行静态的决定并插入这些调用函数。犯错是人之常情,但编译器永远不会忘记插入这些调用的函数。
让咱们在咱们上面的例子中添加另外的一行代码:
fn main() { let mut x = vec!["Hello", "world"]; let y = &x[0]; }
咱们在此介绍了另外的一种绑定 ,y。在这种状况下,y 是向量第一个元素的一个“引用”。Rust 的引用与其余语言中的指针相似,不一样的是有额外的编译时安全检查。特别指出的是,引用与全部权系统经过“借用”来相互做用,而不是经过拥有它。不一样的是,当引用超出范围时,它不会释放底层的内存。若是是那样,咱们将会释放两次内存,这是显然是不正确的!
让咱们来添加第三行代码。表面上来是没错的,可是它会致使一个编译错误:
fn main() { let mut x = vec!["Hello", "world"]; let y = &x[0]; x.push("foo"); }
push 是将一个元素附加到向量组末端的方法。当咱们试图编译这个程序时,咱们将获得一个错误:
error: cannot borrow `x` as mutable because it is also borrowed as immutable x.push("foo"); ^ note: previous borrow of `x` occurs here; the immutable borrow prevents subsequent moves or mutable borrows of `x` until the borrow ends let y = &x[0]; ^ note: previous borrow ends here fn main() { } ^
Rust 编译器给了很详细的错误,这是其中的一次。如错误解释中所说,虽然咱们的绑定是可变的,但咱们仍不能调用 push 方法。这是由于咱们已经有了一个矢量元素的引用 ,y。当另外的一个引用存在时,改变某些变量是危险的行为,由于咱们可能致使引用的无效。在这个特定的例子中,当建立向量时,咱们可能只分配了三个元素的空间。添加第四个元素意味着全部这些元素将会被分配一块新的块内存,同时复制旧值到新内存,更新内部指针到新内存。这些工做都没有什么问题。问题是, y 不会更新,因此咱们会有一个“悬空指针”。那就不对了。在这种状况下,任何的使用引用 y,将会致使错误,因此编译器已经帮咱们捕捉到了这个错误。
那么,咱们如何解决这个问题呢?有两种咱们能够采用的方法。第一种方法,咱们利用拷贝而不是一个引用:
fn main() { let mut x = vec!["Hello", "world"]; let y = x[0].clone(); x.push("foo"); }
在默认状况下,Rust 有移动语义,全部若是咱们想要复制一些数据,咱们能够调用 clone() 方法。在这个例子中 ,y 再也不是存储在 x 中向量的一个引用,而是它的第一个元素“ Hello ”的一个副本。如今没有引用,咱们的 push() 方法能够很好地运行。
若是咱们真的想用一个引用,咱们须要另一种选择:确保在咱们尝试作改变以前,咱们的引用跳出其做用域。写法看起来像这样:
fn main() { let mut x = vec!["Hello", "world"]; { let y = &x[0]; } x.push("foo"); }
咱们用一组额外的大括号建立了一个内部做用域。在咱们调用 push() 以前,y 已经跳出其做用域。因此这样是可行的。
全部权的概念不只有利于防止悬空指针,并且有利于解决与其相关的全部问题,如迭代器失效,并发性等等。
Rust 托管地址:http://wiki.jikexueyuan.com/project/rust/introduction.html| 1b536aeabd7b12eae97798294b2ae3d03 |