mirror of
https://github.com/rust-lang/rustlings.git
synced 2025-12-28 14:59:18 +00:00
翻譯
This commit is contained in:
parent
6dc6b4c61a
commit
8f6d8ec21b
@ -1,12 +1,11 @@
|
||||
# Smart Pointers
|
||||
# 智慧型指標
|
||||
|
||||
In Rust, smart pointers are variables that contain an address in memory and reference some other data, but they also have additional metadata and capabilities.
|
||||
Smart pointers in Rust often own the data they point to, while references only borrow data.
|
||||
在 Rust 中,智慧型指標是包含記憶體位址並引用其他資料的變數,但它們還具有額外的元數據和功能。Rust 中的智慧型指標通常擁有它們指向的資料,而引用僅僅是借用資料。
|
||||
|
||||
## Further Information
|
||||
## 進一步了解
|
||||
|
||||
- [Smart Pointers](https://doc.rust-lang.org/book/ch15-00-smart-pointers.html)
|
||||
- [Using Box to Point to Data on the Heap](https://doc.rust-lang.org/book/ch15-01-box.html)
|
||||
- [Rc\<T\>, the Reference Counted Smart Pointer](https://doc.rust-lang.org/book/ch15-04-rc.html)
|
||||
- [Shared-State Concurrency](https://doc.rust-lang.org/book/ch16-03-shared-state.html)
|
||||
- [Cow Documentation](https://doc.rust-lang.org/std/borrow/enum.Cow.html)
|
||||
- [智慧型指標](https://doc.rust-lang.org/book/ch15-00-smart-pointers.html)
|
||||
- [使用 Box 指向堆上的資料](https://doc.rust-lang.org/book/ch15-01-box.html)
|
||||
- [Rc<T>,引用計數智慧型指標](https://doc.rust-lang.org/book/ch15-04-rc.html)
|
||||
- [共享狀態並發](https://doc.rust-lang.org/book/ch16-03-shared-state.html)
|
||||
- [Cow 文檔](https://doc.rust-lang.org/std/borrow/enum.Cow.html)
|
||||
|
||||
@ -1,29 +1,23 @@
|
||||
// arc1.rs
|
||||
//
|
||||
// In this exercise, we are given a Vec of u32 called "numbers" with values
|
||||
// ranging from 0 to 99 -- [ 0, 1, 2, ..., 98, 99 ] We would like to use this
|
||||
// set of numbers within 8 different threads simultaneously. Each thread is
|
||||
// going to get the sum of every eighth value, with an offset.
|
||||
// 在此練習中,我們有一個 Vec<u32> 稱為 "numbers",其值範圍從 0 到 99 -- [0, 1, 2, ..., 98, 99]
|
||||
// 我們希望在 8 個不同的線程中同時使用這組數字。每個線程將獲得每八個值的總和,並帶有一個偏移量。
|
||||
//
|
||||
// The first thread (offset 0), will sum 0, 8, 16, ...
|
||||
// The second thread (offset 1), will sum 1, 9, 17, ...
|
||||
// The third thread (offset 2), will sum 2, 10, 18, ...
|
||||
// 第一個線程(偏移量為 0),將總結 0, 8, 16, ...
|
||||
// 第二個線程(偏移量為 1),將總結 1, 9, 17, ...
|
||||
// 第三個線程(偏移量為 2),將總結 2, 10, 18, ...
|
||||
// ...
|
||||
// The eighth thread (offset 7), will sum 7, 15, 23, ...
|
||||
// 第八個線程(偏移量為 7),將總結 7, 15, 23, ...
|
||||
//
|
||||
// Because we are using threads, our values need to be thread-safe. Therefore,
|
||||
// we are using Arc. We need to make a change in each of the two TODOs.
|
||||
// 由於我們使用的是線程,我們的值需要是線程安全的。因此,我們使用 Arc。我們需要在兩個 TODO 處進行更改。
|
||||
//
|
||||
// Make this code compile by filling in a value for `shared_numbers` where the
|
||||
// first TODO comment is, and create an initial binding for `child_numbers`
|
||||
// where the second TODO comment is. Try not to create any copies of the
|
||||
// `numbers` Vec!
|
||||
// 通過在第一個 TODO 註釋處填入一個值,使這段代碼能夠編譯,並在第二個 TODO 註釋處創建一個 `child_numbers` 的初始綁定。儘量不要創建 `numbers` Vec 的任何副本!
|
||||
//
|
||||
// Execute `rustlings hint arc1` or use the `hint` watch subcommand for a hint.
|
||||
// 執行 `rustlings hint arc1` 或使用 `hint` watch 子命令以獲取提示。
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
#![forbid(unused_imports)] // Do not change this, (or the next) line.
|
||||
#![forbid(unused_imports)] // 不要更改此行或下一行。
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
|
||||
|
||||
@ -1,22 +1,15 @@
|
||||
// box1.rs
|
||||
//
|
||||
// At compile time, Rust needs to know how much space a type takes up. This
|
||||
// becomes problematic for recursive types, where a value can have as part of
|
||||
// itself another value of the same type. To get around the issue, we can use a
|
||||
// `Box` - a smart pointer used to store data on the heap, which also allows us
|
||||
// to wrap a recursive type.
|
||||
// 在編譯時,Rust 需要知道一個類型佔用了多少空間。這對於遞迴類型來說會變得很麻煩,因為一個值可以包含同類型的另一個值。為了解決這個問題,我們可以使用 `Box` - 一個用來在堆上存儲數據的智能指針,它還允許我們包裝一個遞迴類型。
|
||||
//
|
||||
// The recursive type we're implementing in this exercise is the `cons list` - a
|
||||
// data structure frequently found in functional programming languages. Each
|
||||
// item in a cons list contains two elements: the value of the current item and
|
||||
// the next item. The last item is a value called `Nil`.
|
||||
// 我們在這個練習中實現的遞迴類型是 `cons 列表` - 一種在函數式程式語言中經常出現的資料結構。cons 列表中的每個項目包含兩個元素:當前項目的值和下一個項目。最後一項是一個名為 `Nil` 的值。
|
||||
//
|
||||
// Step 1: use a `Box` in the enum definition to make the code compile
|
||||
// Step 2: create both empty and non-empty cons lists by replacing `todo!()`
|
||||
// 第一步:在枚舉定義中使用 `Box` 來使代碼能夠編譯
|
||||
// 第二步:通過替換 `todo!()` 創建空和非空的 cons 列表
|
||||
//
|
||||
// Note: the tests should not be changed
|
||||
// 注意:不應該更改測試
|
||||
//
|
||||
// Execute `rustlings hint box1` or use the `hint` watch subcommand for a hint.
|
||||
// 執行 `rustlings hint box1` 或使用 `hint` watch 子命令以獲取提示。
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
@ -27,9 +20,9 @@ pub enum List {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("This is an empty cons list: {:?}", create_empty_list());
|
||||
println!("這是一個空的 cons 列表: {:?}", create_empty_list());
|
||||
println!(
|
||||
"This is a non-empty cons list: {:?}",
|
||||
"這是一個非空的 cons 列表: {:?}",
|
||||
create_non_empty_list()
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,16 +1,12 @@
|
||||
// cow1.rs
|
||||
//
|
||||
// This exercise explores the Cow, or Clone-On-Write type. Cow is a
|
||||
// clone-on-write smart pointer. It can enclose and provide immutable access to
|
||||
// borrowed data, and clone the data lazily when mutation or ownership is
|
||||
// required. The type is designed to work with general borrowed data via the
|
||||
// Borrow trait.
|
||||
// 這個練習探索 Cow,也就是 Clone-On-Write 類型。Cow 是一個延遲克隆的智慧指標。
|
||||
// 它可以封裝並提供對借用數據的不可變訪問,並在需要變異或擁有時延遲克隆數據。
|
||||
// 此類型設計為通過 Borrow 特徵來處理通用的借用數據。
|
||||
//
|
||||
// This exercise is meant to show you what to expect when passing data to Cow.
|
||||
// Fix the unit tests by checking for Cow::Owned(_) and Cow::Borrowed(_) at the
|
||||
// TODO markers.
|
||||
// 這個練習旨在讓你了解將數據傳遞給 Cow 時會發生什麼。通過在 TODO 標記處檢查 Cow::Owned(_) 和 Cow::Borrowed(_) 來修復單元測試。
|
||||
//
|
||||
// Execute `rustlings hint cow1` or use the `hint` watch subcommand for a hint.
|
||||
// 執行 `rustlings hint cow1` 或使用 `hint` 子命令以獲取提示。
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
@ -20,7 +16,7 @@ fn abs_all<'a, 'b>(input: &'a mut Cow<'b, [i32]>) -> &'a mut Cow<'b, [i32]> {
|
||||
for i in 0..input.len() {
|
||||
let v = input[i];
|
||||
if v < 0 {
|
||||
// Clones into a vector if not already owned.
|
||||
// 如果還未擁有,則克隆到向量中。
|
||||
input.to_mut()[i] = -v;
|
||||
}
|
||||
}
|
||||
@ -33,18 +29,18 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn reference_mutation() -> Result<(), &'static str> {
|
||||
// Clone occurs because `input` needs to be mutated.
|
||||
// 由於 `input` 需要變異,發生克隆。
|
||||
let slice = [-1, 0, 1];
|
||||
let mut input = Cow::from(&slice[..]);
|
||||
match abs_all(&mut input) {
|
||||
Cow::Owned(_) => Ok(()),
|
||||
_ => Err("Expected owned value"),
|
||||
_ => Err("預期為擁有值"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reference_no_mutation() -> Result<(), &'static str> {
|
||||
// No clone occurs because `input` doesn't need to be mutated.
|
||||
// 由於 `input` 不需要變異,未發生克隆。
|
||||
let slice = [0, 1, 2];
|
||||
let mut input = Cow::from(&slice[..]);
|
||||
match abs_all(&mut input) {
|
||||
@ -54,9 +50,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn owned_no_mutation() -> Result<(), &'static str> {
|
||||
// We can also pass `slice` without `&` so Cow owns it directly. In this
|
||||
// case no mutation occurs and thus also no clone, but the result is
|
||||
// still owned because it was never borrowed or mutated.
|
||||
// 我們也可以直接傳遞 `slice` 而不使用 `&`,這樣 Cow 直接擁有它。
|
||||
// 在這種情況下不發生變異,因此也不會克隆,但結果仍然是擁有的,因為它從未被借用或變異。
|
||||
let slice = vec![0, 1, 2];
|
||||
let mut input = Cow::from(slice);
|
||||
match abs_all(&mut input) {
|
||||
@ -66,9 +61,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn owned_mutation() -> Result<(), &'static str> {
|
||||
// Of course this is also the case if a mutation does occur. In this
|
||||
// case the call to `to_mut()` in the abs_all() function returns a
|
||||
// reference to the same data as before.
|
||||
// 當然,如果發生變異,也是這種情況。
|
||||
// 在這種情況下,對 abs_all() 函數中的 `to_mut()` 調用返回對與之前相同數據的引用。
|
||||
let slice = vec![-1, 0, 1];
|
||||
let mut input = Cow::from(slice);
|
||||
match abs_all(&mut input) {
|
||||
|
||||
@ -1,14 +1,10 @@
|
||||
// rc1.rs
|
||||
//
|
||||
// In this exercise, we want to express the concept of multiple owners via the
|
||||
// Rc<T> type. This is a model of our solar system - there is a Sun type and
|
||||
// multiple Planets. The Planets take ownership of the sun, indicating that they
|
||||
// revolve around the sun.
|
||||
// 在這個練習中,我們想要通過 Rc<T> 類型來表達多個所有者的概念。這是一個我們的太陽系模型 - 有一個 Sun 類型和多個行星。行星擁有太陽,表示它們圍繞著太陽旋轉。
|
||||
//
|
||||
// Make this code compile by using the proper Rc primitives to express that the
|
||||
// sun has multiple owners.
|
||||
// 通過使用適當的 Rc 原語來使這個代碼編譯,表示太陽有多個所有者。
|
||||
//
|
||||
// Execute `rustlings hint rc1` or use the `hint` watch subcommand for a hint.
|
||||
// 執行 `rustlings hint rc1` 或使用 `hint` 子命令以獲取提示。
|
||||
|
||||
// I AM NOT DONE
|
||||
|
||||
@ -38,68 +34,68 @@ impl Planet {
|
||||
#[test]
|
||||
fn main() {
|
||||
let sun = Rc::new(Sun {});
|
||||
println!("reference count = {}", Rc::strong_count(&sun)); // 1 reference
|
||||
println!("引用計數 = {}", Rc::strong_count(&sun)); // 1 個引用
|
||||
|
||||
let mercury = Planet::Mercury(Rc::clone(&sun));
|
||||
println!("reference count = {}", Rc::strong_count(&sun)); // 2 references
|
||||
println!("引用計數 = {}", Rc::strong_count(&sun)); // 2 個引用
|
||||
mercury.details();
|
||||
|
||||
let venus = Planet::Venus(Rc::clone(&sun));
|
||||
println!("reference count = {}", Rc::strong_count(&sun)); // 3 references
|
||||
println!("引用計數 = {}", Rc::strong_count(&sun)); // 3 個引用
|
||||
venus.details();
|
||||
|
||||
let earth = Planet::Earth(Rc::clone(&sun));
|
||||
println!("reference count = {}", Rc::strong_count(&sun)); // 4 references
|
||||
println!("引用計數 = {}", Rc::strong_count(&sun)); // 4 個引用
|
||||
earth.details();
|
||||
|
||||
let mars = Planet::Mars(Rc::clone(&sun));
|
||||
println!("reference count = {}", Rc::strong_count(&sun)); // 5 references
|
||||
println!("引用計數 = {}", Rc::strong_count(&sun)); // 5 個引用
|
||||
mars.details();
|
||||
|
||||
let jupiter = Planet::Jupiter(Rc::clone(&sun));
|
||||
println!("reference count = {}", Rc::strong_count(&sun)); // 6 references
|
||||
println!("引用計數 = {}", Rc::strong_count(&sun)); // 6 個引用
|
||||
jupiter.details();
|
||||
|
||||
// TODO
|
||||
let saturn = Planet::Saturn(Rc::new(Sun {}));
|
||||
println!("reference count = {}", Rc::strong_count(&sun)); // 7 references
|
||||
println!("引用計數 = {}", Rc::strong_count(&sun)); // 7 個引用
|
||||
saturn.details();
|
||||
|
||||
// TODO
|
||||
let uranus = Planet::Uranus(Rc::new(Sun {}));
|
||||
println!("reference count = {}", Rc::strong_count(&sun)); // 8 references
|
||||
println!("引用計數 = {}", Rc::strong_count(&sun)); // 8 個引用
|
||||
uranus.details();
|
||||
|
||||
// TODO
|
||||
let neptune = Planet::Neptune(Rc::new(Sun {}));
|
||||
println!("reference count = {}", Rc::strong_count(&sun)); // 9 references
|
||||
println!("引用計數 = {}", Rc::strong_count(&sun)); // 9 個引用
|
||||
neptune.details();
|
||||
|
||||
assert_eq!(Rc::strong_count(&sun), 9);
|
||||
|
||||
drop(neptune);
|
||||
println!("reference count = {}", Rc::strong_count(&sun)); // 8 references
|
||||
println!("引用計數 = {}", Rc::strong_count(&sun)); // 8 個引用
|
||||
|
||||
drop(uranus);
|
||||
println!("reference count = {}", Rc::strong_count(&sun)); // 7 references
|
||||
println!("引用計數 = {}", Rc::strong_count(&sun)); // 7 個引用
|
||||
|
||||
drop(saturn);
|
||||
println!("reference count = {}", Rc::strong_count(&sun)); // 6 references
|
||||
println!("引用計數 = {}", Rc::strong_count(&sun)); // 6 個引用
|
||||
|
||||
drop(jupiter);
|
||||
println!("reference count = {}", Rc::strong_count(&sun)); // 5 references
|
||||
println!("引用計數 = {}", Rc::strong_count(&sun)); // 5 個引用
|
||||
|
||||
drop(mars);
|
||||
println!("reference count = {}", Rc::strong_count(&sun)); // 4 references
|
||||
println!("引用計數 = {}", Rc::strong_count(&sun)); // 4 個引用
|
||||
|
||||
// TODO
|
||||
println!("reference count = {}", Rc::strong_count(&sun)); // 3 references
|
||||
println!("引用計數 = {}", Rc::strong_count(&sun)); // 3 個引用
|
||||
|
||||
// TODO
|
||||
println!("reference count = {}", Rc::strong_count(&sun)); // 2 references
|
||||
println!("引用計數 = {}", Rc::strong_count(&sun)); // 2 個引用
|
||||
|
||||
// TODO
|
||||
println!("reference count = {}", Rc::strong_count(&sun)); // 1 reference
|
||||
println!("引用計數 = {}", Rc::strong_count(&sun)); // 1 個引用
|
||||
|
||||
assert_eq!(Rc::strong_count(&sun), 1);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user