Rust常用特型之TryFrom和TryInto特型

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

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

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

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

rust 复制代码
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。我们在处理返回值时可以根据返回的是否错误来决定下一步怎么办,例如

rust 复制代码
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的参数为一闭包函数。

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

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

rust 复制代码
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里关联多种类型。

相关推荐
Java编程爱好者12 小时前
十万个why:加了 LIMIT 1,为什么查询反而变慢了?
后端
JavaTalks12 小时前
高并发保护实战:限流、熔断、降级如何配合落地
后端·架构·设计
代码丰12 小时前
为什么Java 接口中的存在 Static 和 Default 方法?
后端
用户5711551768312 小时前
深入解析Spring BeanPostProcessor
后端
掘金者阿豪14 小时前
🚀 CentOS Stream 9服务器Docker部署KWDB:从零到跨模查询实战全记录
后端
yang_xin_yu14 小时前
一文带你精通泛型PECS原则与四大核心函数式接口
后端
孟陬14 小时前
国外技术周刊 #1:Paul Graham 重新分享最受欢迎的文章《创作者的品味》、本周被划线最多 YouTube《如何在 19 分钟内学会 AI》、为何我不
java·前端·后端
树獭叔叔14 小时前
13-KV Cache与位置编码表:大模型推理加速的核心技术
后端·aigc·openai
想用offer打牌14 小时前
一站式了解四种限流算法
java·后端·go
嘻哈baby14 小时前
用 C++ 写线程池是怎样一种体验?
后端