2024-06-18 18:29:13 +08:00

73 lines
2.3 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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
}
}
}