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トレイトを使って、アストリッドの特別な材料の型に対するカスタム型変換を作成することです。
アストリッドの測定値は、正の値にも負の値にもなることがあります(符号付き整数)。しかし、特定の作業では、値が常に正であること(符号なし整数)を保証する必要があります。
次の変換を行う関数を書いて、アストリッドを手伝いましょう。
i32)から符号なし整数(u16)へ。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"
アストリッドは、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
}