• Rust常用特型之TryFrom和TryInto特型


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

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

    由于Rust并不是很明确怎样从i64转换成i32,因此它并没有实现为i32实现From(但反过来实现了),因为这种转换会丢失信息,其它会丢失信息的数字转换也是一样没有实现。作为替代,i32实现了TryFrom。同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>;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

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

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

    上面的转换如果超过了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
      }
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

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

    impl TryInto<LinearShift> for Transform {
      type Error = TransformError;
      fn try_into(self) -> Result<LinearShift, Self::Error> {
        if !self.normalized() {
          return Err(TransformError::NotNormalized);
        }
      ...
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

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

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

  • 相关阅读:
    Jwt 介绍
    C++学习——C++中const的新花样
    微信小程序结合php后台实现登录授权机制详解
    同步和异步
    微服务结合领域驱动设计落地
    Ubuntu下载
    详细介绍Unlink的原理及分析
    最新大厂数据湖面试题,知识点总结
    分布式开发漫谈
    【LeetCode力扣】86. 分隔链表
  • 原文地址:https://blog.csdn.net/weixin_39430411/article/details/138000307