學習軌道
/
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特質

對於可能失敗的轉換,請使用TryInto,它會回傳一個Option:

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情況
  • 在有號與無號型別之間轉換時,要考慮溢位與下溢

說明

Astrid 是一位愛探險的鍊金術師,她正試著把從不同國度收集來的魔法度量單位標準化。 有些國度使用有號數值(可以是負數),有些則使用無號數值(永遠是正數)。 除此之外,Astrid 還為某些稀有材料準備了兩個自訂型別,她需要一個能輕鬆在這些型別之間轉換的方法。

你的任務是幫 Astrid 在有號與無號整數之間轉換,並運用 Cairo 的Into和TryInto特徵,為她那些特殊材料型別建立自訂的型別轉換。

1. 在有號與無號之間轉換魔法單位

Astrid 的測量值有時是正數、有時是負數(有號整數),但某些任務需要她確保這些值永遠是正數(無號整數)。

來幫幫 Astrid 吧,寫一個函式來轉換:

  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. 自訂材料型別轉換

Astrid 會用到兩種稀有材料,Essence和Elixir,它們以自訂型別表示。 她希望能把Essence轉成Elixir,但反過來則不行。

幫幫 Astrid 建立Essence和Elixir兩個自訂型別,並實作Into特徵,把Essence轉成Elixir。

寫一個接受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,全部免費。