【发布时间】:2020-07-08 13:56:27
【问题描述】:
From trait 的文档有以下关于 trait 本身和任何可能的失败的说明:
人们应该总是更喜欢实现
From而不是Into,因为实现From会自动提供Into的实现,这要归功于标准库中的一揽子实现。
和
注意:这个特性不能失败。如果转换失败,请使用
TryFrom。
我有以下From 实现将整数转换为罗马数字:
/// ### UpperRoman
/// Upper-case Roman numerals. The `None` variant is for handling invalid conversions.
pub enum UpperRoman {
M,
CM,
D,
CD,
C,
XC,
L,
XL,
X,
IX,
V,
IV,
I,
None,
}
impl From<u32> for UpperRoman {
/// ### from
/// Converts a `u32` to an `UpperRoman` numeral variant.
fn from(numeral: u32) -> Self {
match numeral {
1000 => Self::M,
900 => Self::CM,
500 => Self::D,
400 => Self::CD,
100 => Self::C,
90 => Self::XC,
50 => Self::L,
40 => Self::XL,
10 => Self::X,
9 => Self::IX,
5 => Self::V,
4 => Self::IV,
1 => Self::I,
_ => Self::None,
}
}
}
只有少数有效案例。对于任何无效输入,我定义了一个变体UpperRoman::None,这意味着没有与给定输入匹配的罗马数字。这会处理任何失败情况,因此满足文档中设置的要求。
如果我想使用自动生成的Into-trait 实现将罗马数字转换回整数怎么办? UpperRoman::into 函数如何处理 UpperRoman::None 情况?在调用函数之前,我唯一的选择是匹配UpperRoman::into 的可能输入以确保它不是UpperRoman::None 变体吗?
【问题讨论】:
-
Into<u32> for UpperRoman没有自动生成的实现。将有一个Into<UpperRoman> for u32的实现,即对于您手动实现的相同转换。 -
"自动生成
Into-trait 实现将罗马数字转换回整数" → 没有这样的东西。当您定义From<u32> for UpperRoman时,您会自动获得Into<UpperRoman> for u32,而不是Into<u32> for UpperRoman。From不需要像您发现的那样是双射的,也不需要按照您的方式实现,因此编译器无法猜测如何生成其他方式。 -
在
UpperRoman中不包含None的情况会更惯用,而是在值可能为None时使用TryFrom和Option<UpperRoman>。
标签: enums rust type-conversion traits