轨道
/
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,但反过来不行。

请创建两个自定义类型Essence和Elixir,并实现Into特征,把Essence转换为Elixir,以此帮助 Astrid。

请编写一个函数,接受一个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,全部免费。