トラック
/
Cairo
Cairo
/
演習
/
魔法の測定
魔法の測定

魔法の測定

学習演習

はじめに

Cairoの型変換を使うと、データをある型から別の型へ変換できます。柔軟で安全なデータ操作ができるようになります。

基本

Cairoには、型変換のための仕組みがいくつか用意されています。

直接キャスト

互換性のある数値型であれば、直接キャストを使えます。

let small_number: u8 = 42;
let big_number: u32 = small_number.into();

Intoトレイト

Intoトレイトを使うと、ある型から別の型へ変換できます。

let value: u16 = 100;
let converted: u32 = value.into();

TryIntoトレイト

失敗する可能性のある変換には、Optionを返すTryIntoを使います。

let large_value: u32 = 70000;
let small_value: Option<u16> = large_value.try_into();

match small_value {
    Option::Some(v) => println!("Converted: {}", v),
    Option::None => println!("Conversion failed"),
}

独自の型変換

自分で定義した型にIntoを実装することもできます。

#[derive(Drop)]
struct Celsius {
    value: i32,
}

#[derive(Drop)]
struct Fahrenheit {
    value: i32,
}

impl CelsiusIntoFahrenheit of Into<Celsius, Fahrenheit> {
    fn into(self: Celsius) -> Fahrenheit {
        Fahrenheit { value: (self.value * 9) / 5 + 32 }
    }
}

安全性に関する注意点

  • 変換が失敗する可能性があるとき(大きい型から小さい型への変換など)は、TryIntoを使います
  • 変換が必ず成功するときは、Intoを使います
  • TryIntoが返すOption::Noneの場合は必ず処理しましょう
  • 符号付き型と符号なし型の間で変換するときは、オーバーフローとアンダーフローに注意しましょう

説明

冒険好きの錬金術師アストリッドは、さまざまな世界から集めた魔法の計量単位を標準化しようとしています。 世界によっては符号付きの測定値(負の値もあり得ます)を使い、別の世界では符号なしの測定値(常に正の値)を使っています。 さらにアストリッドには、ある珍しい材料のための2つのカスタム型があり、これらの型の間で簡単に変換する方法が必要です。

今回の目標は、アストリッドが符号付き整数と符号なし整数の間で変換できるようにし、CairoのIntoとTryIntoトレイトを使って、アストリッドの特別な材料の型に対するカスタム型変換を作成することです。

1. 符号付きと符号なしの魔法の単位の変換

アストリッドの測定値は、正の値にも負の値にもなることがあります(符号付き整数)。しかし、特定の作業では、値が常に正であること(符号なし整数)を保証する必要があります。

次の変換を行う関数を書いて、アストリッドを手伝いましょう。

  1. 符号付き整数(i32)から符号なし整数(u16)へ。
  2. 符号なし整数(u16)から符号付き整数(i32)へ。
let signed_value: i32 = -42;
match convert_signed_to_unsigned(signed_value) {
    Option::Some(v) => println!("Converted to unsigned: {}", v),
    Option::None => println!("Failed to convert: {}", signed_value),
} // prints "Failed to convert: -42"

let unsigned_value: u16 = 42;
let signed_value: i32 = convert_unsigned_to_signed(unsigned_value);
println!("Converted to signed: {}", signed_value); // prints "Converted to signed: 42"

2. 材料のカスタム型の変換

アストリッドは、EssenceとElixirという2つの珍しい材料を扱っています。これらはカスタム型で表されます。 アストリッドは、EssenceをElixirに変換できるようにしたいと考えていますが、その逆は望んでいません。

2つのカスタム型EssenceとElixirを作成し、EssenceからElixirへの変換を行うIntoトレイトを実装して、アストリッドを手伝いましょう。

Essenceを受け取り、.into()を使ってElixirに変換する関数を書いてみましょう。

#[derive(Drop)]
struct Essence {
    potency: u16,
}

#[derive(Drop)]
struct Elixir {
    strength: u16,
}

fn convert_essence_to_elixir(essence: Essence) -> Elixir {
    // Convert the Essence to Elixir using the Into trait.
    essence.into()
}

fn main() {
    let essence = Essence { potency: 100 };
    let elixir: Elixir = convert_essence_to_elixir(essence);
    println!("Elixir strength: {}", elixir.strength); // Elixir strength: 100
}
GitHubで編集する リンクは新しいウィンドウまたはタブで開きます
Cairo Exercism

魔法の測定を始める準備はできましたか?

Exercismに登録すれば、25個のコンセプト68個の演習、そして本物の人間によるメンタリングとともに、Cairoを学んでマスターできます。すべて無料です。