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里关联多种类型。

相关推荐
芳草萋萋鹦鹉洲哦9 分钟前
【vue3+tauri+rust】如何实现下载文件mac+windows
windows·macos·rust
二进制person43 分钟前
Java SE--方法的使用
java·开发语言·算法
OneQ6661 小时前
C++讲解---创建日期类
开发语言·c++·算法
码农不惑2 小时前
2025.06.27-14.44 C语言开发:Onvif(二)
c语言·开发语言
程序员岳焱3 小时前
Java 与 MySQL 性能优化:Java 实现百万数据分批次插入的最佳实践
后端·mysql·性能优化
麦兜*3 小时前
Spring Boot启动优化7板斧(延迟初始化、组件扫描精准打击、JVM参数调优):砍掉70%启动时间的魔鬼实践
java·jvm·spring boot·后端·spring·spring cloud·系统架构
Coding小公仔3 小时前
C++ bitset 模板类
开发语言·c++
大只鹅4 小时前
解决 Spring Boot 对 Elasticsearch 字段没有小驼峰映射的问题
spring boot·后端·elasticsearch
ai小鬼头4 小时前
AIStarter如何快速部署Stable Diffusion?**新手也能轻松上手的AI绘图
前端·后端·github
小赖同学啊4 小时前
物联网数据安全区块链服务
开发语言·python·区块链