トラック
/
Cairo
Cairo
/
演習
/
クロノレルム・クロノチェイン
クロノレルム・クロノチェイン

クロノレルム・クロノチェイン

学習演習

はじめに

Cairoのスマートポインターは、通常のポインターに安全機能を追加することで、安全で効率的なメモリ管理を実現する高度なデータ構造です。nullポインターの参照解除や、初期化されていないメモリへのアクセスといったよくある問題を防ぎます。

スマートポインターとは?

スマートポインターは通常のポインターと同じように振る舞いますが、所有権を追跡し、安全なメモリアクセスを保証することで、nullポインターやダングリングポインターの参照解除といった問題を防ぎます。

スマートポインターの種類

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も扱います。Chrono Chainとは、連なったTimeNodeの並びで、それぞれが特定の瞬間を表します。 Chrono Chainは、連続する瞬間がまっすぐにつながった道筋で、それぞれのTimeNodeが次のノードにつながっています。 このChrono Chainは、一連の特定の出来事をたどっていくときに役立ちます。Time Keepersが1本のタイムラインを追えるようになるからです。

しかし、こうした長くなる可能性のあるChrono Chainを扱うために、Time KeepersはSmart Pointers (Box<t>)<strong>を使い、瞬間のリストを安全に管理してたどります。不要なメモリの複製やオーバーフローを起こさないためです。 それぞれの</strong>TimeNode</t>は次のノードへの参照を持ち、再帰的な構造を作ります。

見習いとしての課題は、スマートポインターを使ってChrono Chainを再帰的なリスト構造として実装することです。

この演習では、次のことを行います。

  1. 瞬間のリストを表す、再帰的なChronoChain列挙型を作成します。
  2. 再帰的なノードを格納するために、Box<T>スマートポインターを使います。
  3. u32の値の配列からChronoChainを作る関数を実装します。
  4. ChronoChainをたどり、リストに格納された値の合計を求める関数を実装します。

1. 再帰的なChronoChain列挙型を定義する

2つのバリアントを持つ再帰的な列挙型ChronoChainを作成します。

  • End:リストの終わりを表します。
  • Link:u32の値と、チェーン内の次のノードへのボックス化された参照を持ちます。

2. ChronoChainを組み立てる関数を作成する

u32の値の配列を受け取り、ChronoChainを返すChronoChain::build関数を書きます。値はスマートポインターを使って順番につなぎます。

3. 合計を求める関数を実装する

ChronoChainを再帰的にたどり、すべてのノードの値の合計を求めるChronoChain::sum関数を書きます。

使用例

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を学んでマスターできます。すべて無料です。