「Rust 中方便和习惯性的转换」TryFrom和错误

「这是我参与11月更文挑战的第 19 天,活动详情查看:2021最后一次更文挑战


尝试:TryFrom

我们看到,由From和Into进行的转换不能失败。然而,有时我们处理的类型并不完全相互映射,所以我们需要这些trait的易错版本。

幸运的是,有 TryFromTryInto,它们返回一个 Result<TargetType, ErrorType>。这两个trait和它们NB的兄弟姐妹一起存在于std::convert中,但它们的确切细节和含义仍在讨论中,这意味着它们仍被标记为不稳定。为了使用它们,我们可以将自己限制在编译器的nightly版本中,使用 try_from,或者将它们的定义粘贴在我们的库中的某个文件中(它们真的很短)。

让我们来看看TryFrom的定义(截至Rust 1.10.0):

#[unstable(feature = "try_from", issue = "33417")]
pub trait TryFrom<T>: Sized {
    /// The type returned in the event of a conversion error.
    type Err;

    /// Performs the conversion.
    fn try_from(T) -> Result<Self, Self::Err>;
}
复制代码

首先,我们有一个稳定性属性,标志着该特性是不稳定的,然后是特性定义本身。我们可以看到它有一个相关的类型,Err,用于转换失败的情况。正如预期的那样,我们有一个try_from方法而不是from,它返回Result<Self, Self::Err>而不是Self。

继续我们的例子:

impl TryFrom<u8> for PacketType {
    type Err = ParseError;
    fn try_from(original: u8) -> Result<Self, Self::Err> {
        match original {
            0 => Ok(PacketType::Data),
            1 => Ok(PacketType::Fin),
            2 => Ok(PacketType::State),
            3 => Ok(PacketType::Reset),
            4 => Ok(PacketType::Syn),
            n => Err(ParseError::InvalidPacketType(n))
        }
    }
}
复制代码

在这个例子中,对于可以映射的值,我们返回相应的 PacketType 变量,对于其余的值,我们返回一个错误。这个错误类型保留了原始值,这对调试有潜在的帮助,但其实我们可以直接丢弃它。

AsRef and AsMut

最后我们看看std::convert模块中剩下的trait,放到最后并非是它们不重要。AsRef和AsMut。像convert模块中的其他trait一样,它们被用来实现类型间的转换。

然而,其他特质会消耗数值,并可能执行重的操作,而 AsRef 和 AsMut 是用来实现轻便的,引用到引用的转换。

你可能已经从它们的名字中猜到了,AsRef将一个不可变的值的引用转换为另一个不可变的引用,而AsMut对可变的引用做同样的转换。

由于它们都非常相似,我们同时看看它们。让我们从它们的定义开始:

#[stable(feature = "rust1", since = "1.0.0")]
pub trait AsRef<T: ?Sized> {
    /// Performs the conversion.
    #[stable(feature = "rust1", since = "1.0.0")]
    fn as_ref(&self) -> &T;
}

#[stable(feature = "rust1", since = "1.0.0")]
pub trait AsMut<T: ?Sized> {
    /// Performs the conversion.
    #[stable(feature = "rust1", since = "1.0.0")]
    fn as_mut(&mut self) -> &mut T;
}
复制代码

Guess you like

Origin juejin.im/post/7034862561367425032