Menu
CoddyTech

From 和 Into

本课属于 Coddy Rust 学习旅程的“面向对象编程”单元。第 57 课,共 61 课。

在 Rust 中,类型之间的转换是一项常见任务。From trait 提供了一种标准化的方式,用于定义如何从一种类型创建另一种类型。实现 From 后,你就能自动免费获得 Into trait。

要实现 From,你需要定义如何从另一种类型构造你的类型:

struct Meters(f64);
struct Kilometers(f64);

impl From<Kilometers> for Meters {
    fn from(km: Kilometers) -> Self {
        Meters(km.0 * 1000.0)
    }
}

现在你可以使用 from 函数或 into 方法进行转换:

let distance = Kilometers(5.0);

// 显式使用 From
let m1 = Meters::from(distance);

// 使用 Into(因为实现了 From,所以可以这样用)
let distance = Kilometers(3.0);
let m2: Meters = distance.into();

由于 Rust 需要知道你要转换成什么类型,因此 into() 方法需要类型注解。当你有需要转换为主要类型的辅助结构体时,这种模式特别有用,例如将配置数据转换为已初始化的对象,或将原始输入转换为经过验证的结构。

challenge icon

挑战

简单

让我们使用 From trait 构建一个温度转换系统!你将创建两种温度类型,Celsius 和 Fahrenheit,并使用 Rust 的标准转换 trait 实现它们之间的转换。

你将在两个文件中组织代码:

  • temperature.rs:定义两个公开的新类型结构体 Celsius 和 Fahrenheit,它们都封装一个 f64。实现 From trait,使用公式 fahrenheit = celsius × 1.8 + 32.0 将 Celsius 转换为 Fahrenheit。还要为每个结构体添加一个 value 方法,用于返回内部的 f64。
  • main.rs:引入温度模块,并演示两种转换方式。根据提供的输入创建一个 Celsius 值,然后使用 Fahrenheit::from() 将它转换为 Fahrenheit。再创建另一个 Celsius 值,并使用 .into() 方法进行转换。打印两种转换结果。

从 Celsius 到 Fahrenheit 的转换公式是:乘以 1.8,再加上 32。请记住,实现 From<Celsius> for Fahrenheit 后,Celsius 会自动免费获得 Into<Fahrenheit> trait!

两个温度都会以整数形式打印:使用 as i64 转换每个 f64,小数部分会向零截断。因此,输入 36.6 会打印为 36C,转换得到的 97.88 华氏度会打印为 97F。不会向上取整。

输出应按以下格式显示两种转换结果:

From: {celsius1}C = {fahrenheit1}F
Into: {celsius2}C = {fahrenheit2}F

例如,输入 0 和 100 时:

From: 0C = 32F
Into: 100C = 212F

输入 25 和 -40 时:

From: 25C = 77F
Into: -40C = -40F

你会收到两个输入:第一个 Celsius 值(解析为 f64)和第二个 Celsius 值(解析为 f64)。

亲手试试

mod temperature;

use temperature::{Celsius, Fahrenheit};

fn main() {
    // 读取输入
    let mut input1 = String::new();
    std::io::stdin().read_line(&mut input1).expect("Failed to read line");
    let celsius1: f64 = input1.trim().parse().expect("Invalid number");
    
    let mut input2 = String::new();
    std::io::stdin().read_line(&mut input2).expect("Failed to read line");
    let celsius2: f64 = input2.trim().parse().expect("Invalid number");
    
    // TODO:根据 celsius1 创建一个 Celsius 值
    // TODO:使用 Fahrenheit::from() 将它转换为 Fahrenheit
    
    // TODO:根据 celsius2 再创建一个 Celsius 值
    // TODO:使用 .into() 将它转换为 Fahrenheit
    
    // TODO:按以下格式输出结果:
    // From: {celsius1}C = {fahrenheit1}F
    // Into: {celsius2}C = {fahrenheit2}F
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: Rust 在线编译器