學習軌道
/
Cairo
Cairo
/
練習
/
時序之境:時序鏈
時序之境:時序鏈

時序之境:時序鏈

學習練習

簡介

Cairo 中的智慧指標是進階的資料結構,它們在一般指標之上加入各種安全機制,確保記憶體管理既安全又有效率,並避免對空指標解參考或存取未初始化記憶體這類常見問題。

什麼是智慧指標?

智慧指標的行為就像一般指標,但它會追蹤所有權,並確保記憶體存取安全,避免對空指標或懸空指標解參考這類問題。

智慧指標的型別

Cairo 提供了幾種智慧指標型別,例如 Box<T> 和 Nullable<T>:

  • Box<T>:將資料存放在特殊的記憶體區段中,很適合大型或動態大小的資料。它可以在不複製資料的情況下轉移所有權。
  • Nullable<T>:指向型別 T 的有效值或 null,適合用來處理選擇性的值。

記憶體安全

智慧指標有助於避免不安全的記憶體存取,確保記憶體在不再需要時自動釋放,進而降低記憶體洩漏的風險。

範例:用 Box<T> 處理遞迴型別

像 Box<T> 這樣的智慧指標能安全地處理遞迴型別,例如二元樹,它會有效率地配置記憶體,避免無限遞迴。

use core::box::{BoxTrait};

#[derive(Copy, Drop)]
enum BinaryTree {
    Leaf: u32,
    Node: (u32, Box<BinaryTree>, Box<BinaryTree>),
}

fn main() {
    let leaf1 = BinaryTree::Leaf(1);
    let leaf2 = BinaryTree::Leaf(2);
    let node = BinaryTree::Node((3, BoxTrait::new(leaf1), BoxTrait::new(leaf2)));
    println!("{:?}", node);
}

效能優勢

智慧指標會傳遞資料的參考,而不是複製大型結構,藉此提升效能並降低記憶體額外負擔。

// `Cart` is a large struct that contains a lot of information
fn pass_pointer(cart: Box<Cart>) {
    let cart = cart.unbox();
    println!("{} is shopping today and bought {} items", cart.buyer, cart.items);
}

說明

在Chrono Realms裡,Time Keepers 要處理的不只是時間軸形成的樹,還有 Chrono Chain,也就是一連串相連的 TimeNode,每個節點代表時間中的某個特定時刻。 Chrono Chain 是由連續時刻構成的直線路徑,每個 TimeNode 都連向下一個節點。 當你需要穿梭於一連串特定事件時,Chrono Chain 就很好用,因為它讓 Time Keepers 能沿著單一時間軸前進。

不過,為了處理這些可能很長的 Chrono Chain,Time Keepers 會使用智慧指標(Box<t>)</t>,安全地管理和走訪這些時刻串列,避免不必要的記憶體複製或溢位。 每個 TimeNode 都持有指向下一個節點的參考,形成遞迴結構。

身為學徒,你的任務就是用智慧指標把 Chrono Chain 實作成遞迴的串列結構。

在這道練習中,你會:

  1. 建立一個遞迴的 ChronoChain 列舉,用來表示一串時刻。
  2. 使用 Box<T> 智慧指標來儲存遞迴的節點。
  3. 實作一個函式,從 u32 值的陣列建立 ChronoChain。
  4. 實作一個函式,走訪 ChronoChain 並加總串列中儲存的值。

1. 定義遞迴的 ChronoChain 列舉

建立一個有兩個變體的遞迴列舉 ChronoChain:

  • End:代表串列的結尾。
  • Link:包含一個 u32 值,以及指向鏈中下一個節點的裝箱參考。

2. 建立 ChronoChain 的函式

撰寫一個函式 ChronoChain::build,接受 u32 值的陣列並回傳 ChronoChain,用智慧指標把這些值依序串接起來。

3. 實作加總函式

撰寫一個函式 ChronoChain::sum,遞迴走訪 ChronoChain,加總所有節點的值。

範例用法

fn main() {
    // Create a ChronoChain from an array of values
    let chrono_chain = ChronoChain::build(array![10, 20, 30]);

    // Sum the values in the ChronoChain
    let total_sum = chrono_chain.sum();

    println!("Total Time Power: {}", total_sum);
}
透過 GitHub 編輯 連結會在新視窗或分頁中開啟
Cairo Exercism

準備好開始 時序之境:時序鏈 了嗎?

註冊 Exercism,透過 25 個概念68 個練習 和真人引導來學習並精通 Cairo,全部免費。