mirror of
https://github.com/rust-lang/rustlings.git
synced 2025-12-29 07:19:17 +00:00
73 lines
2.3 KiB
Rust
73 lines
2.3 KiB
Rust
// cow1.rs
|
||
//
|
||
// 這個練習探索 Cow,也就是 Clone-On-Write 類型。Cow 是一個延遲克隆的智慧指標。
|
||
// 它可以封裝並提供對借用數據的不可變訪問,並在需要變異或擁有時延遲克隆數據。
|
||
// 此類型設計為通過 Borrow 特徵來處理通用的借用數據。
|
||
//
|
||
// 這個練習旨在讓你了解將數據傳遞給 Cow 時會發生什麼。通過在 TODO 標記處檢查 Cow::Owned(_) 和 Cow::Borrowed(_) 來修復單元測試。
|
||
//
|
||
// 執行 `rustlings hint cow1` 或使用 `hint` 子命令以獲取提示。
|
||
|
||
// I AM NOT DONE
|
||
|
||
use std::borrow::Cow;
|
||
|
||
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 {
|
||
// 如果還未擁有,則克隆到向量中。
|
||
input.to_mut()[i] = -v;
|
||
}
|
||
}
|
||
input
|
||
}
|
||
|
||
#[cfg(test)]
|
||
mod tests {
|
||
use super::*;
|
||
|
||
#[test]
|
||
fn reference_mutation() -> Result<(), &'static str> {
|
||
// 由於 `input` 需要變異,發生克隆。
|
||
let slice = [-1, 0, 1];
|
||
let mut input = Cow::from(&slice[..]);
|
||
match abs_all(&mut input) {
|
||
Cow::Owned(_) => Ok(()),
|
||
_ => Err("預期為擁有值"),
|
||
}
|
||
}
|
||
|
||
#[test]
|
||
fn reference_no_mutation() -> Result<(), &'static str> {
|
||
// 由於 `input` 不需要變異,未發生克隆。
|
||
let slice = [0, 1, 2];
|
||
let mut input = Cow::from(&slice[..]);
|
||
match abs_all(&mut input) {
|
||
// TODO
|
||
}
|
||
}
|
||
|
||
#[test]
|
||
fn owned_no_mutation() -> Result<(), &'static str> {
|
||
// 我們也可以直接傳遞 `slice` 而不使用 `&`,這樣 Cow 直接擁有它。
|
||
// 在這種情況下不發生變異,因此也不會克隆,但結果仍然是擁有的,因為它從未被借用或變異。
|
||
let slice = vec![0, 1, 2];
|
||
let mut input = Cow::from(slice);
|
||
match abs_all(&mut input) {
|
||
// TODO
|
||
}
|
||
}
|
||
|
||
#[test]
|
||
fn owned_mutation() -> Result<(), &'static str> {
|
||
// 當然,如果發生變異,也是這種情況。
|
||
// 在這種情況下,對 abs_all() 函數中的 `to_mut()` 調用返回對與之前相同數據的引用。
|
||
let slice = vec![-1, 0, 1];
|
||
let mut input = Cow::from(slice);
|
||
match abs_all(&mut input) {
|
||
// TODO
|
||
}
|
||
}
|
||
}
|