트랙
/
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 Keeper들은 시간선의 트리뿐만 아니라 Chrono Chains, 즉 각각 특정 시점을 나타내는 TimeNodes가 연결된 연속체를 자주 다뤄요. Chrono Chain은 순차적인 시점들이 일직선으로 이어진 경로이고, 각 TimeNode는 다음 노드로 이어져요. 이런 Chrono Chains는 일련의 특정 사건들을 따라 이동할 때 유용한데, Time Keeper가 하나의 시간선을 따라갈 수 있게 해주기 때문이에요.

그런데 이렇게 길어질 수 있는 Chrono Chains를 다루기 위해 Time Keeper들은 **스마트 포인터(Box<t>)**를 사용해서, 불필요한 메모리 중복이나 오버플로 없이 이 시점 리스트들을 안전하게 관리하고 순회해요. 각 <strong>TimeNode</strong>는 다음 노드에 대한 참조를 가지고 있어서 재귀적인 구조를 이뤄요.</t>

견습생으로서 해야 할 일은 스마트 포인터를 사용해 Chrono Chain을 재귀적인 리스트 구조로 구현하는 거예요.

이 연습 문제에서는 다음을 해봐요:

  1. 시점들의 리스트를 나타내는 재귀적인 ChronoChain 열거형을 만들어요.
  2. 재귀적인 노드를 저장하기 위해 Box<T> 스마트 포인터를 사용해요.
  3. u32 값들의 배열로 ChronoChain을 만드는 함수를 구현해요.
  4. ChronoChain을 순회하면서 리스트에 저장된 값들을 모두 더하는 함수를 구현해요.

1. 재귀적인 ChronoChain 열거형 정의하기

두 가지 변형을 가진 재귀적인 열거형 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에 가입하고 Cairo 트랙을 개념 25개연습 문제 68개, 그리고 실제 사람의 멘토링과 함께 배우고 익혀 보세요. 모두 무료예요.