Rust常用特型之TryFrom和TryInto特型

在Rust标准库中,存在很多常用的工具类特型,它们能帮助我们写出更具有Rust风格的代码。

我们前面学习了了FromInto特型,今天我们来学们一下两个相似的特型TryFromTryInto。看名字就知道他们是试图转换的意思,那为什么有试图转换?在前面的学习中我们也介绍过,FromInto是转换不能失败的,但是有时转换需求是会失败的,例如字符串转数字,你怎么把英文字母转成数字呢?所以转换可能成功,可能失败,这时就需要使用TryFromTryInto特型了。

由于Rust并不是很明确怎样从i64转换成i32,因此它并没有实现为i32实现From<i64>(但反过来实现了),因为这种转换会丢失信息,其它会丢失信息的数字转换也是一样没有实现。作为替代,i32实现了TryFrom<i64>。同FromInto特型的关系一样,TryFromTryInto也是对称的,你实现了TryFrom,则目标类型的TryInto也自动实现了。

他们的定义仅是比FromInto特型复杂一点:

pub trait TryFrom<T>: Sized {
  type Error;
  fn try_from(value: T) -> Result<Self, Self::Error>;
}
pub trait TryInto<T>: Sized {
  type Error;
  fn try_into(self) -> Result<T, Self::Error>;
}

因为有可能转换失败,所以try_into函数返回一个Result。我们在处理返回值时可以根据返回的是否错误来决定下一步怎么办,例如

use std::convert::TryInto;
// Saturate on overflow, rather than wrapping
let smaller: i32 = huge.try_into().unwrap_or(i32::MAX);

上面的转换如果超过了i32的最大值,则返回错误,因此unwrap_or函数会使用一个i32的最大值作为smaller的值。

这里直接使用默认值时无法进一步灵活选择,下面的代码在出错时根据转换的是正还是负值从而返回不同的值,此时unwrap_or_else的参数为一闭包函数。

let smaller: i32 = huge.try_into().unwrap_or_else(|_|{
  if huge >= 0 {
    i32::MAX
  } else {
    i32::MIN
  }
});

在你自己的类型上实现可失败的转换也很容易。根据程序需求和功能不同,转换失败时的错误类型Error可以比较简单或者稍微复杂。上面的例子中,由于唯一可能发生的错误为溢出,标准库使用了一个空结构体来代表错误发生本身这个信息,不再提供其它额外信息。相对的,复杂类型的转换有可能需要返回更多的关于错误的信息,例如下面的代码。

impl TryInto<LinearShift> for Transform {
  type Error = TransformError;
  fn try_into(self) -> Result<LinearShift, Self::Error> {
    if !self.normalized() {
      return Err(TransformError::NotNormalized);
    }
  ...
  }
}

上面的例子中,返回的TransformError包含多个枚举变量,因此它返回值有附带进一步信息,而不像之前的示例只有溢出这一种错误。

FromInto用来处理相关类型的简单转换,TryFromTryInto拓展了这种转换,增加了错误处理,因为复杂转换可能会失败。这四种特型可以一起使用来在一个crate里关联多种类型。

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AiMateZero

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值