# Rust 編程語言
> [README.md](https://github.com/rust-lang/rust/blob/master/src/doc/book/README.md)
commit 3a6dbb30a21be8d237055479af613e30415b0c56
歡迎閱讀!這本書將教會你使用[Rust編程語言](http://www.rust-lang.org/)。Rust 是一個注重安全與速度的現代系統編程語言,通過在沒有垃圾回收的情況下保證內存安全來實現它的目標,這使它成為一個在能夠許多其它語言并不適合的用例中大展身手的語言:嵌入到其它語言中,在特定的時間和空間要求下編程,和編寫例如設備驅動和操作系統這樣的底層代碼。它通過一系列的不產生運行時開銷的編譯時安全檢查來提升目前語言所關注的領域,同時消除一切數據競爭。Rust同時也意在實現“零開銷抽象”,即便在這些抽象看起來比較像一個高級語言的特性。即便如此,Rust也允許你像一個底層語言那樣進行精確的控制。
《Rust編程語言》被分為數個部分。這個介紹是第一部分。之后是:
- [準備](#) - 為你的電腦安裝 Rust 開發環境
- [學習Rust](#) - 通過一個小項目來學習 Rust 編程
- [語法和語義](#) - Rust 各個部分,被拆分成小的部分講解
- [高效Rust](#) - 編寫優秀 Rust 代碼的高級內容
- [Rust開發版](#) - 還未出現在穩定版本中的最新功能
- [詞匯表](#) - 書中使用的術語的參考
- [參考文獻](#) - 影響過 Rust 的文獻,關于 Rust 的論文
在閱讀了介紹這部分之后,你可以根據喜好深入到“學習Rust”或“語法和語義”部分:如果你想通過項目深入了解,可以先選擇“學習 Rust”;如果你想從頭開始,并且學習一個完整的內容再學習另一個,你可以從“語法和語義”開始。豐富的交叉連接將這些部分聯系到一起。
### 貢獻
生成這本書(英文版)的源文件可以在 [GitHub](https://github.com/rust-lang/rust/tree/master/src/doc/book) 上找到。
> 以下內容在最新版中并未出現,暫時保留
> ## Rust 簡介
> Rust 是你會感興趣的語言嗎?讓我們檢查一些小的代碼例子來展示它的部分威力。
使 Rust 顯得獨一無二的主要概念是“所有權”。考慮這個小例子:
~~~
fn main() {
let mut x = vec!["Hello", "world"];
}
~~~
這個程序創建了一個叫做`x`的[變量綁定](#)。這個綁定的值是一個`Vec<T>`,一個 vector,我們通過一個定義在標準庫中的[宏](#)來創建它。這個宏叫做`vec`,并且我們通過一個`!`調用宏。這遵循了 Rust 的一般原則:讓一切明了。宏可以做比函數調用復雜的多的多的工作,并且它們在視覺上也是有區別的。`!`也方便了解析,更容易編寫工具,這也是很重要的。
我們使用了`mut`來使`x`可變:在 Rust 中綁定是默認是不可變的。在下面的例子中這個 vector 是可變的。
另外值得注意的是這里我們并不需要一個類型注釋:因為 Rust 是靜態類型的,我們并不需要顯式的標明類型。Rust 擁有類型推斷來平衡靜態類型的能力和類型注釋的冗余。
Rust 與堆分配相比傾向于棧分配:`x`被直接儲存在棧上。然而,`Vec<T>`類型在堆上為 vector 的元素分配了空間。如果你并不熟悉這里的區別,目前你可以忽略它,或者看看[“棧和堆”](#)。作為一個系統編程語言,Rust 給予你控制內存分配的能力,不過當我們上手后,這并不是什么大問題。
之前,我們提到“所有權”是 Rust 中的一個關鍵概念。在 Rust 用語中,`x`被認為“擁有”這個 vector。這意味著當`x`離開作用域,vector 的內存將被銷毀。這由 Rust 編譯器決定,而不是通過類似垃圾回收器這樣的機制。換句話說,在 Rust 中,你并不需要自己調用像`malloc`和`free`這樣的函數:編譯器靜態決定何時你需要分配和銷毀內存,并自動調用這些函數。人非圣賢孰能無過,不過編譯器永遠也不會忘記。
讓我們為例子再加一行:
~~~
fn main() {
let mut x = vec!["Hello", "world"];
let y = &x[0];
}
~~~
我們引入了另一個綁定,`y`。在這個例子中,`y`是對 vector 第一個元素的“引用”。Rust 的引用類似于其它語言中的指針,不過帶有額外的編譯時安全檢查。引用用[“借用”](#)它指向的內容,而不是擁有它,來與所有權系統交互。這里的區別是,當一個引用離開作用域,它不會釋放之下的內存。如果它這么做了,我們會釋放兩次,這是很糟的!。
讓我們增加第三行。這看起來并不會引起錯誤,不過實際上會造成一個編譯錯誤:
~~~
fn main() {
let mut x = vec!["Hello", "world"];
let y = &x[0];
x.push("foo");
}
~~~
`push`是 vector 的一個方法,它在 vector 的末尾附加另一個元素。當嘗試編譯這個程序時,我們得到一個錯誤:
~~~
error: cannot borrow `x` as mutable because it is also borrowed as immutable
x.push(4);
^
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`。這是因為我們已經有了一個 vector 元素的引用,`y`。當有其它引用存在時改變值是危險的,因為我們可能使這個引用無效。在這個特定的例子中,當我們創建了 vector,我們可能只分配了 3 個元素的空間。增加一個元素意味著將分配一個新的能放下所有 4 個元素的空間,拷貝舊的值,并更新內部的指針指向這個內存。所有這些都木有問題。問題是`y`并沒有被更新,很糟糕地,`y`成了一個“懸垂指針”(dangling pointer)。因此,在這個例子中任何對`y`的使用都會引起錯誤,而編譯器會為我們捕獲了這個錯誤。
該如何解決這個問題呢?這里我們可以采取兩個方法。第一個方法是使用拷貝而非引用:
~~~
fn main() {
let mut x = vec!["Hello", "world"];
let y = x[0].clone();
x.push("foo");
}
~~~
Rust 默認擁有[移動語義](#),所以如果想要拷貝一些數據,我們調用`clone()`方法。在這個例子中,`y`不再是一個儲存在`x`中 vector 的一個引用,而是它第一個元素的拷貝,`"hello"`。現在我們并不擁有一個引用,所以`push()`就能正常工作。
如果真心需要一個引用,我們需要另一種方法:確保在嘗試修改之前,讓引用離開作用域。如下:
~~~
fn main() {
let mut x = vec!["Hello", "world"];
{
let y = &x[0];
}
x.push("foo");
}
~~~
用一對大括號創建了一個內部作用域,`y`會在調用`push()`之前離開作用域,所以我們不會碰到問題。
所有權的概念并不僅僅善于防止懸垂指針,也解決了一整個系列的相關問題,比如迭代器無效,并發和其它問題。
- 前言
- 貢獻者
- 1.介紹
- 2.準備
- 3.學習 Rust
- 3.1.猜猜看
- 3.2.哲學家就餐問題
- 3.3.其它語言中的 Rust
- 4.語法和語義
- 4.1.變量綁定
- 4.2.函數
- 4.3.原生類型
- 4.4.注釋
- 4.5.If語句
- 4.6.循環
- 4.7.所有權
- 4.8.引用和借用
- 4.9.生命周期
- 4.10.可變性
- 4.11.結構體
- 4.12.枚舉
- 4.13.匹配
- 4.14.模式
- 4.15.方法語法
- 4.16.Vectors
- 4.17.字符串
- 4.18.泛型
- 4.19.Traits
- 4.20.Drop
- 4.21.if let
- 4.22.trait 對象
- 4.23.閉包
- 4.24.通用函數調用語法
- 4.25.crate 和模塊
- 4.26.const和static
- 4.27.屬性
- 4.28.type別名
- 4.29.類型轉換
- 4.30.關聯類型
- 4.31.不定長類型
- 4.32.運算符和重載
- 4.33.Deref強制多態
- 4.34.宏
- 4.35.裸指針
- 4.36.不安全代碼
- 5.高效 Rust
- 5.1.棧和堆
- 5.2.測試
- 5.3.條件編譯
- 5.4.文檔
- 5.5.迭代器
- 5.6.并發
- 5.7.錯誤處理
- 5.8.選擇你的保證
- 5.9.外部函數接口
- 5.10.Borrow 和 AsRef
- 5.11.發布途徑
- 5.12.不使用標準庫
- 6.Rust 開發版
- 6.1.編譯器插件
- 6.2.內聯匯編
- 6.4.固有功能
- 6.5.語言項
- 6.6.鏈接進階
- 6.7.基準測試
- 6.8.裝箱語法和模式
- 6.9.切片模式
- 6.10.關聯常量
- 6.11.自定義內存分配器
- 7.詞匯表
- 8.語法索引
- 9.參考文獻
- 附錄:名詞中英文對照