Rust从入门到实战系列三百零一:From/Into

From 特征允许让一个类型定义如何基于另一个类型来创建自己,因此它提供了一个很方便的类型转换的
方式。
From 和 Into 是配对的,我们只要实现了前者,那后者就会自动被实现:只要实现了 impl From
for U , 就可以使用以下两个方法: let u: U = U::from(T) 和 let u:U = T.into() ,前者由 From 特
征提供,而后者由自动实现的 Into 特征提供。
需要注意的是,当使用 into 方法时,你需要进行显式地类型标注,因为编译器很可能无法帮我们推导出
所需的类型。
来看一个例子,我们可以简单的将 &str 转换成 String
fn main() {
let my_str = “hello”;
// 以下三个转换都依赖于一个事实:String 实现了 From<&str> 特征
let string1 = String::from(my_str);
let string2 = my_str.to_string();
// 这里需要显式地类型标注
let string3: String = my_str.into();
}
这种转换可以发生是因为标准库已经帮我们实现了 From 特征: impl From<&'_ str> for String 。你
还可以在这里)找到其它实现 From 特征的常用类型。

  1. 🌟🌟🌟
    fn main() {
    // impl From for i32
    let i1:i32 = false.into();
    let i2:i32 = i32::from(false);
    assert_eq!(i1, i2);
    assert_eq!(i1, 0);
    // 使 用 两 种 方 式 修 复 错 误
    // 1. 哪 个 类 型 实 现 From 特 征 : impl From for ? , 你 可 以 查 看 一 下 之 前 提 到 的 文 档 ,
    // 2. 上 一 章 节 中 介 绍 过 的 某 个 关 键 字
    let i3: i32 = ‘a’.into();
    // 使 用 两 种 方 法 来 解 决 错 误
    let s: String = ‘a’ as String;
    println!(“Success!”)
    }
    为自定义类型实现 From 特征
  2. 🌟🌟
    // From 被 包 含 在 std::prelude 中 , 因 此 我 们 没 必 要 手 动 将 其 引 入 到 当 前 作 用 域 来
    // use std::convert::From;
    #[derive(Debug)]
    struct Number {
    value: i32,
    }
    impl From for Number {
    // 实 现 from 方 法
    }
    // 填 空
    fn main() {
    let num = __(30);
    assert_eq!(num.value, 30);
    let num: Number = __;
    assert_eq!(num.value, 30);
    println!(“Success!”)
    }
  3. 🌟🌟🌟 当执行错误处理时,为我们自定义的错误类型实现 From 特征是非常有用。这样就可以通
    过 ? 自动将某个错误类型转换成我们自定义的错误类型
    use std::fs;
    use std::io;
    use std::num;
    enum CliError {
    IoError(io::Error),
    ParseError(num::ParseIntError),
    }
    impl Fromio::Error for CliError {
    // 实 现 from 方 法
    }
    impl Fromnum::ParseIntError for CliError {
    // 实 现 from 方 法
    }
    fn open_and_parse_file(file_name: &str) -> Result<i32, CliError> {
    // ? 自 动 将 io::Error 转 换 成 CliError
    let contents = fs::read_to_string(&file_name)?;
    // num::ParseIntError -> CliError
    let num: i32 = contents.trim().parse()?;
    Ok(num)
    }
    fn main() {
    println!(“Success!”)
    }
    TryFrom/TryInto
    类似于 From 和 Into , TryFrom 和 TryInto 也是用于类型转换的泛型特征。
    但是又与 From/Into 不同, TryFrom 和 TryInto 可以对转换后的失败进行处理,然后返回一个
    Result 。
  4. 🌟🌟
    // TryFrom 和 TryInto 也 被 包 含 在 std::prelude 中, 因 此 以 下 引 入 是 没 必 要 的
    // use std::convert::TryInto;
    fn main() {
    let n: i16 = 256;
    // Into 特 征 拥 有 一 个 方 法into,
    // 因 此 TryInto 有 一 个 方 法 是 ?
    let n: u8 = match n.__() {
    Ok(n) => n,
    Err(e) => {
    println!(“there is an error when converting: {:?}, but we catch it”, e.to_str
    0
    }
    };
    assert_eq!(n, __);
    println!(“Success!”)
    }
  5. 🌟🌟🌟
    #[derive(Debug, PartialEq)]
    struct EvenNum(i32);
    impl TryFrom for EvenNum {
    type Error = ();
    // 实 现 try_from
    fn try_from(value: i32) -> Result<Self, Self::Error> {
    if value % 2 == 0 {
    Ok(EvenNum(value))
    } else {
    Err(())
    }
    }
    }
    fn main() {
    assert_eq!(EvenNum::try_from(8), Ok(EvenNum(8)));
    assert_eq!(EvenNum::try_from(5), Err(()));
    // 填 空
    let result: Result<EvenNum, ()> = 8i32.try_into();
    assert_eq!(result, __);
    let result: Result<EvenNum, ()> = 5i32.try_into();
    assert_eq!(result, __);
    println!(“Success!”)
    }
  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值