Skip to content

Commit

Permalink
Merge pull request #192 from jrycw/fix-typo-plus-some-tweaks
Browse files Browse the repository at this point in the history
Fix typo + tweak
  • Loading branch information
weihanglo authored Dec 26, 2023
2 parents 08bc647 + fae0ef8 commit ed7fb63
Show file tree
Hide file tree
Showing 20 changed files with 26 additions and 26 deletions.
2 changes: 1 addition & 1 deletion listings/ch20-web-server/listing-20-14/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ impl ThreadPool {
let mut threads = Vec::with_capacity(size);

for _ in 0..size {
// 就產生些執行緒並儲存至向量
// 將產生些執行緒並儲存至向量
}

ThreadPool { threads }
Expand Down
2 changes: 1 addition & 1 deletion src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
- [發佈 Crate 到 Crates.io](ch14-02-publishing-to-crates-io.md)
- [Cargo 工作空間](ch14-03-cargo-workspaces.md)
- [透過 `cargo install` 安裝執行檔](ch14-04-installing-binaries.md)
- [透過自訂命命來擴展 Cargo 的功能](ch14-05-extending-cargo.md)
- [透過自訂命令來擴展 Cargo 的功能](ch14-05-extending-cargo.md)

- [智慧指標](ch15-00-smart-pointers.md)
- [使用 `Box<T>` 指向堆積上的資料](ch15-01-box.md)
Expand Down
2 changes: 1 addition & 1 deletion src/ch03-01-variables-and-mutability.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 * 3;
```

變數的名稱為 `THREE_HOURS_IN_SECONDS` ,且它的數值被設為 60(一分鐘有多少秒)乘上 60(一小時有多少分鐘)乘上 3(此程式想要計算的小時數量)。Rust 的常數命名規則為使用全部英文大寫並用底寫區隔每個單字。編譯器能夠在編譯時用特定限制集合內的操作進行運算,讓我們能用易於理解且驗證的方式寫出此數值,而不用將常數設爲 10,800。你可以查閱 Rust Reference 的 [constant evaluation 段落][const-eval]來瞭解哪些操作可以在宣告常數時使用。
變數的名稱為 `THREE_HOURS_IN_SECONDS` ,且它的數值被設為 60(一分鐘有多少秒)乘上 60(一小時有多少分鐘)乘上 3(此程式想要計算的小時數量)。Rust 的常數命名規則為使用全部英文大寫並用底線區隔每個單字。編譯器能夠在編譯時用特定限制集合內的操作進行運算,讓我們能用易於理解且驗證的方式寫出此數值,而不用將常數設爲 10,800。你可以查閱 Rust Reference 的 [constant evaluation 段落][const-eval]來瞭解哪些操作可以在宣告常數時使用。

在整支程式運行時,常數在它們的範圍內都是有效的。這樣的性質讓常數在處理應用程式中需要被許多程式碼部份所知道的數值的情況下是非常好的選擇,像是一款遊戲中玩家能夠得到的最高分數或者光速的數值。

Expand Down
4 changes: 2 additions & 2 deletions src/ch03-04-comments.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

```rust
// 這邊處理的事情很複雜,長到
// 我們需要多行註解來能解釋
// 我們需要多行註解來解釋
// 希望此註解能幫助你理解。
```

Expand All @@ -34,4 +34,4 @@

Rust 還有另一種註解:技術文件註解。我們會在第十四章的[「發佈 Crate 到 Crates.io」][publishing]<!-- ignore -->段落提到它。

[publishing]: ch14-02-publishing-to-crates-io.html
[publishing]: ch14-02-publishing-to-crates-io.html
2 changes: 1 addition & 1 deletion src/ch03-05-control-flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
{{#include ../listings/ch03-common-programming-concepts/no-listing-27-if-false/output.txt}}
```

還有一件值得注意的是程式碼的條件判斷**必須**`bool`。如果條件不是 `bool` 的話,我們就會遇到錯誤。比方說,試試以下程式碼:
還有一點值得注意的是程式碼的條件判斷**必須**`bool`。如果條件不是 `bool` 的話,我們就會遇到錯誤。比方說,試試以下程式碼:

<span class="filename">檔案名稱:src/main.rs</span>

Expand Down
2 changes: 1 addition & 1 deletion src/ch07-01-packages-and-crates.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

**函式庫(Library)crate** 則不會有 `main` 函式,而且它們也不會編譯成執行檔。這種 crate 定義的功能用來分享給多重專案使用。舉例來說,我們在[第二章][rand]<!-- ignore -->用到的 `rand` crate 就提供了產生隨機數值的功能。當大多數的 Rustacean 講到「crate」時,他們其實指的是函式庫 crate,所以他們講到「crate」時相當於就是在講其他程式語言概念中的「函式庫」。

**crate 的源頭**會是一個原始檔案,讓 Rust 的編譯器可以作為起始點並組織 crate 模組的地方(我們會在[「定義模組來控制作用域與隱私權」][modules]<!-- ignore -->的段落更加解釋模組)。
**crate 的源頭**會是一個原始檔案,讓 Rust 的編譯器可以作為起始點並組織 crate 模組的地方(我們會在[「定義模組來控制作用域與隱私權」][modules]<!-- ignore -->的段落詳加解釋模組)。

**套件**(package)則是提供一系列功能的一或數個 crate。一個套件會包含一個 *Cargo.toml* 檔案來解釋如何建構那些 crate。Cargo 本身其實就是個套件,包含了你已經用來建構程式碼的命令列工具。Cargo 套件還包含執行檔 crate 需要依賴的函式庫 crate。其他專案可以依賴 Cargo 函式庫來使用與 Cargo 命令列工具用到的相同邏輯功能。

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

### 模組懶人包

這裡我們先快速帶過模組、路徑、`use` 關鍵字以及 `pub` 關鍵字在編譯器中是怎麼運作的,以及多數開發者會怎麼組織他們的程式碼。我們會在此章節透過範例逐依介紹,不過這裡能讓你快速理解模組是怎麼運作的。
這裡我們先快速帶過模組、路徑、`use` 關鍵字以及 `pub` 關鍵字在編譯器中是怎麼運作的,以及多數開發者會怎麼組織他們的程式碼。我們會在此章節透過範例逐一介紹,不過這裡能讓你快速理解模組是怎麼運作的。

- **從 crate 源頭開始**:在編譯 crate 時,編譯器會先尋找 crate 源頭檔案(函式庫 crate 的話,通常就是 *src/lib.rs*;執行檔 crate 的話,通常就是 *src/main.rs*)來編譯程式碼。
- **宣告模組**:在 crate 源頭檔案中,你可以宣告新的模組,比如說你宣告了一個「garden」模組 `mod garden;`。編譯器會在以下這幾處尋找模組的程式碼:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ Rust 選擇這樣的模組系統,讓內部實作細節預設都是隱藏起來

<span class="caption">範例 7-6:編譯範例 7-5 時產生的錯誤</span>

到底發生了什麼事?在 `mod hosting` 之前加上 `pub` 關鍵字確實公開了模組。有了這項修改後,我們的確可以在取得 `front_of_house` 的後繼續進入 `hosting`。但是 `hosting` 的所有**內容**仍然是私有的。模組中的 `pub` 關鍵字只會讓該模組公開讓上層模組使用而已,而不是存取它所有的內部程式碼。因為模組相當於一個容器,如果我們只公開模組的話,本身並不能做多少事情。我們需要再進一步選擇公開模組內一些項目才行。
到底發生了什麼事?在 `mod hosting` 之前加上 `pub` 關鍵字確實公開了模組。有了這項修改後,我們的確可以在取得 `front_of_house` 後,繼續進入 `hosting`。但是 `hosting` 的所有**內容**仍然是私有的。模組中的 `pub` 關鍵字只會讓該模組公開讓上層模組使用而已,而不是存取它所有的內部程式碼。因為模組相當於一個容器,如果我們只公開模組的話,本身並不能做多少事情。我們需要再進一步選擇公開模組內一些項目才行。

範例 7-6 的錯誤訊息表示 `add_to_waitlist` 函式是私有的。隱私權規則如同模組一樣適用於結構體、列舉、函式與方法。

Expand Down
2 changes: 1 addition & 1 deletion src/ch10-00-generics.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,6 @@
2. 將重複的程式碼提取置函式本體內,並指定函式簽名輸入與回傳數值。
3. 更新重複使用程式碼的實例,改呼叫我們定義的函式。

接著我們將以相同的步驟來使用泛型來減少重複的程式碼。就像函式本體可以抽象出 `list` 而不用特定數值,泛型允許程式碼執行抽象型別。
接著我們將以相同的步驟使用泛型來減少重複的程式碼。就像函式本體可以抽象出 `list` 而不用特定數值,泛型允許程式碼執行抽象型別。

舉例來說,假設我們有兩個函式:一個會找出 `i32` 型別切片中的最大值而另一個會找出 `char` 型別切片的最大值。我們要如何刪除重複的部分呢?讓我們拭目以待!
2 changes: 1 addition & 1 deletion src/ch10-01-syntax.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## 泛型資料型別

我們使用泛型(generics)來建立項目的定義,像是函式簽名或結構體,讓我們在之後可以使用在不同的實際資料型別。讓我們先看看如何使用泛型定義函式、列舉與方法。然後我們會在來看泛型對程式碼的效能影響如何
我們使用泛型(generics)來建立項目的定義,像是函式簽名或結構體,讓我們之後可以使用在不同的實際資料型別。讓我們先看看如何使用泛型定義函式、列舉與方法。然後我們會再來看泛型對程式碼的效能影響如何

### 在函式中定義

Expand Down
2 changes: 1 addition & 1 deletion src/ch10-02-traits.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

舉例來說,如果我們有數個結構體各自擁有不同種類與不同數量的文字:結構體 `NewsArticle` 儲存特定地點的新聞故事,然後 `Tweet` 則有最多 280 字元的內容,且有個欄位來判斷是全新的推文、轉推或其他推文的回覆。

我們想要建立ㄧ個多媒體聚集器函式庫 crate 叫 `aggregator` 來顯示可能存在 `NewsArticle``Tweet` 實例的資料總結。要達成此目的的話,我們需要每個型別的總結,且我們會呼叫該實例的 `summarize` 方法來索取總結。範例 10-12 顯示了表達此行為的 `Summary` 特徵定義。
我們想要建立一個多媒體聚集器函式庫 crate 叫 `aggregator` 來顯示可能存在 `NewsArticle``Tweet` 實例的資料總結。要達成此目的的話,我們需要每個型別的總結,且我們會呼叫該實例的 `summarize` 方法來索取總結。範例 10-12 顯示了表達此行為的 `Summary` 特徵定義。

<span class="filename">檔案名稱:src/lib.rs</span>

Expand Down
4 changes: 2 additions & 2 deletions src/ch11-03-test-organization.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ adder

如果我們的專案只包含 *src/main.rs* 檔案的執行檔 crate 而沒有 *src/lib.rs* 檔案的話,我們無法在 *tests* 目錄下建立整合測試,也無法將 *src/main.rs* 檔案中定義的函式透過 `use` 陳述式引入作用域。只有函式庫 crate 能公開函式給其他 crate 使用,執行檔 crate 只用於獨自執行。

這也是為何 Rust 專案為執行檔提供直白的 *src/main.rs* 檔案並允許呼叫 *src/lib.rs* 檔案中的邏輯程式碼。使用這樣子的架構的話,整合測試**可以**透過 `use` 來測試函式庫 crate,並讓重點功能可以公開使用。如果重點功能可以運作的話,那 *src/main.rs* 檔案中剩下的程式碼部分也能夠如期執行,而這一小部分就不必特定做測試
這也是為何 Rust 專案為執行檔提供直白的 *src/main.rs* 檔案並允許呼叫 *src/lib.rs* 檔案中的邏輯程式碼。使用這樣子的架構的話,整合測試**可以**透過 `use` 來測試函式庫 crate,並讓重點功能可以公開使用。如果重點功能可以運作的話,那 *src/main.rs* 檔案中剩下的程式碼部分也能夠如期執行,而這一小部分就不必特地做測試

## 總結

Expand All @@ -150,4 +150,4 @@ Rust 的測試功能提供了判定程式碼怎樣才算正常運作的方法,
[paths]: ch07-03-paths-for-referring-to-an-item-in-the-module-tree.html
[separating-modules-into-files]:
ch07-05-separating-modules-into-different-files.html
[alt-paths]: ch07-05-separating-modules-into-different-files.html#其他種的檔案路徑
[alt-paths]: ch07-05-separating-modules-into-different-files.html#其他種的檔案路徑
4 changes: 2 additions & 2 deletions src/ch13-01-closures.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ let add_one_v4 = |x| x + 1 ;

### `Fn` 特徵以及將獲取的數值移出閉包

一旦閉包從其定義的周圍環境獲取了數值的參考或所有權(也就是說被**移入**閉包中),閉包本體的程式碼會定義閉包在之後執行結束後要對參考或數值做什麼事情(也就是說被**移出**閉包)。閉包本體可以做以下的事情:將獲取的數值移出閉包、改變獲取的數值、不改變且不移動數值,或是一開始就不從環境獲取任何值。
一旦閉包從其定義的周圍環境獲取了數值的參考或所有權(也就是說被**移入**閉包中),閉包本體的程式碼會定義閉包在執行結束後要對參考或數值做什麼事情(也就是說被**移出**閉包)。閉包本體可以做以下的事情:將獲取的數值移出閉包、改變獲取的數值、不改變且不移動數值,或是一開始就不從環境獲取任何值。

閉包從周圍環境獲取並處理數值的方式會影響閉包會實作哪種特徵,而這些特徵能讓函式與結構體決定它們想使用哪種閉包。閉包會依照閉包本體處理數值的方式,自動實作一種或多種 `Fn` 特徵:

Expand Down Expand Up @@ -209,4 +209,4 @@ impl<T> Option<T> {

當我們要在函式或型別中定義與使用閉包時,`Fn` 特徵是很重要的。在下個段落中,我們將討論疊代器。疊代器有許多方法都需要閉包引數,所以隨著我們繼續下去別忘了複習閉包的用法!

[unwrap-or-else]: ../std/option/enum.Option.html#method.unwrap_or_else
[unwrap-or-else]: ../std/option/enum.Option.html#method.unwrap_or_else
4 changes: 2 additions & 2 deletions src/ch15-01-box.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ Box 沒有額外的效能開銷,就只是將它們的資料儲存在堆積上

<span class="caption">範例 15-4:嘗試定義遞迴列舉所得到的錯誤</span>

錯誤顯示此型別的「大小為無限」,原因是因為我們定義的 `List` 有個變體是遞迴:它直接存有另一個相同類型的數值。所以 Rust 無法判別出它需要多少空間才能儲存一個 `List` 的數值。讓我進一步研究為何我們會得到這樣的錯誤,首先來看 Rust 如何決定要配置多少空間來儲存非遞迴型別。
錯誤顯示此型別的「大小為無限」,原因是因為我們定義的 `List` 有個變體是遞迴:它直接存有另一個相同類型的數值。所以 Rust 無法判別出它需要多少空間才能儲存一個 `List` 的數值。讓我們進一步研究為何會得到這樣的錯誤,首先來看 Rust 如何決定要配置多少空間來儲存非遞迴型別。

#### 計算非遞迴型別的大小

Expand All @@ -92,7 +92,7 @@ Box 沒有額外的效能開銷,就只是將它們的資料儲存在堆積上

要決定一個 `Message` 數值需要配置多少空間,Rust 會遍歷每個變體來看哪個變體需要最大的空間。Rust 會看到 `Message::Quit` 不佔任何空間、`Message::Move` 需要能夠儲存兩個 `i32` 的空間,以此類推。因為只有一個變體會被使用,一個 `Message` 數值所需的最大空間就是其最大變體的大小。

將此對應到當 Rust 嘗試檢查像是範例 15-2 的 `List` 列舉來決定遞迴型別需要多少空間時,究竟會發生什麼事。編譯器先從查看 `Cons` 的變體開始,其存有一個 `i32` 型別與一個 `List` 型別。因此 `Cons` 需要的空間大小為 `i32` 的大小加上 `List` 的大小。為了要瞭解 `List` 型別需要的多少記憶體,編譯器在進一步看它的變體,也是從 `Cons` 變體開始。`Cons` 變體存有一個型別 `i32` 與一個型別 `List`,而這樣的過程就無限處理下去,如圖示 15-1 所示。
將此對應到當 Rust 嘗試檢查像是範例 15-2 的 `List` 列舉來決定遞迴型別需要多少空間時,究竟會發生什麼事。編譯器先從查看 `Cons` 的變體開始,其存有一個 `i32` 型別與一個 `List` 型別。因此 `Cons` 需要的空間大小為 `i32` 的大小加上 `List` 的大小。為了要瞭解 `List` 型別需要的多少記憶體,編譯器再進一步看它的變體,也是從 `Cons` 變體開始。`Cons` 變體存有一個型別 `i32` 與一個型別 `List`,而這樣的過程就無限處理下去,如圖示 15-1 所示。

<img alt="An infinite Cons list" src="img/trpl15-01.svg" class="center" style="width: 50%;" />

Expand Down
2 changes: 1 addition & 1 deletion src/ch15-04-rc.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

我們可以嘗試改用參考來變更 `Cons` 的定義,但是這樣我們就必須指定生命週期參數。透過指定生命週期參數,我們會指定列表中的每個元素會至少活得跟整個列表一樣久。範例 15-17 的元素和列表雖然可以這樣,但不是所有的場合都是如此。

我們最後可以改用 `Rc<T>` 來變更 `List` 的定義,如範例 15-18 所示。每個 `Cons` 變體都會存有一個數值以及一個由 `Rc<T>` 指向的 `List`。當我們建立 `b` 時,不會取走 `a` 的所有權,我們會克隆(clone) `a` 存有的 `Rc<List>`,因而增加參考的數量從一增加到二,並讓 `a``b` 共享 `Rc<List>` 資料的所有權。我們也在在建立 `c` 時克隆 `a`,增加參考的數量從二增加到三。每次我們呼叫 `Rc::clone` 時,對 `Rc<List>` 資料的參考計數就會成增加,然後資料不會被清除直到沒有任何參考為止。
我們最後可以改用 `Rc<T>` 來變更 `List` 的定義,如範例 15-18 所示。每個 `Cons` 變體都會存有一個數值以及一個由 `Rc<T>` 指向的 `List`。當我們建立 `b` 時,不會取走 `a` 的所有權,我們會克隆(clone) `a` 存有的 `Rc<List>`,因而增加參考的數量從一增加到二,並讓 `a``b` 共享 `Rc<List>` 資料的所有權。我們也在建立 `c` 時克隆 `a`,增加參考的數量從二增加到三。每次我們呼叫 `Rc::clone` 時,對 `Rc<List>` 資料的參考計數就會成增加,然後資料不會被清除直到沒有任何參考為止。

<span class="filename">檔案名稱:src/main.rs</span>

Expand Down
2 changes: 1 addition & 1 deletion src/ch15-05-interior-mutability.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
* `Box<T>` 能有不可變或可變的借用並在編譯時檢查;`Rc<T>` 則只能有不可變借用並在編譯時檢查:`RefCell<T>` 能有不可變或可變借用但是在執行時檢查。
* 由於 `RefCell<T>` 允許在執行時檢查可變參考,你可以改變 `RefCell<T>` 內部的數值,就算 `RefCell<T>` 是不可變的。

改變不可變數值內部的值就**內部可變性**模式。讓我們看看內部可變性何時會有用,且觀察為何是可行的。
改變不可變數值內部的值稱為**內部可變性**模式。讓我們看看內部可變性何時會有用,且觀察為何是可行的。

### 內部可變性:不可變數值的可變借用

Expand Down
2 changes: 1 addition & 1 deletion src/ch17-03-oo-design-patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@

我們仍然有 `Post::new` 函式,但是它沒有回傳 `Post` 實例,而是回傳了 `DraftPost` 的實例。因為 `content` 是私有的,而且沒有任何函式回傳 `Post`,所以目前沒有任何辦法能建立 `Post` 的實例。

`DraftPost` 結構體有個 `add_text` 方法,所以我們可以像之前一樣為 `content` 新增文字,但注意到 `DraftPost` 沒有定義 `content` 方法!所以現在程式確保所有文章都已草稿為起始,而且文章草稿不會提供顯示其內容的方法。任何想嘗試繞過此約束的方式都會產生編譯錯誤。
`DraftPost` 結構體有個 `add_text` 方法,所以我們可以像之前一樣為 `content` 新增文字,但注意到 `DraftPost` 沒有定義 `content` 方法!所以現在程式確保所有文章都以草稿為起始,而且文章草稿不會提供顯示其內容的方法。任何想嘗試繞過此約束的方式都會產生編譯錯誤。

#### 透過不同型別的轉移來實作狀態轉換

Expand Down
Loading

0 comments on commit ed7fb63

Please sign in to comment.