我正在为我的一个项目创建一个 Bit 枚举,并且我经历了与
as u32
(或任何其他类型)语法的一些奇怪的交互。我已经为我的 Bit 枚举实现了 IntoBit as u32
,有点假设它是 .into()
的语法糖。我运行了一些失败的测试,在试图找到错误时,我发现我的 Bit 枚举的布局如下:
pub enum Bit {
On,
Off,
}
我一时兴起将其更改为:
pub enum Bit {
Off,
On,
}
什么也没想。我重新运行测试,看看哪个测试再次失败,令我惊讶的是,另外 2 个测试通过了!
我做了一些额外的挖掘,来回切换
On
和 Off
并将 as u32
更改为 .into()
调用。看起来 as u32
完全忽略了任何 Into 实现,只转换位。这有点道理,但是对于 u32 as f64
来说,它是如何工作的?您不能简单地在那里转换位。它具体有什么作用?
查看建议的问题,似乎我的枚举正在使用
TryFrom
实现(这也已实现)。但这对我来说没有意义,为什么 rust 使用 TryFrom
实现可能会对具体实现的 Into
感到恐慌?但即使这样的解释也没有意义,因为 TryFrom
实现专门将 0 映射到 Bit::Off,1 映射到 Bit::On,并将所有其他值映射到错误。
通常我会查看此文档,但我不知道在哪里可以专门找到此文档,因为它更多的是一种语言功能而不是某个东西的实现,指向它的指针也有帮助!
作为参考,这是我使用
as u32
的地方:
fn bits_flipped(left: &BitString, right: &BitString) -> u32 {
assert_eq!(
left.len(),
right.len(),
"the length of the bitstrings is not equal. Left is {} and right is {}",
left.len(),
right.len()
);
let mut difference: u32 = 0;
for i in 0..left.len() {
difference += (left[i] ^ right[i]) as u32; // This line was causing issues
}
difference
}
这是我用于
Into
实现的宏:
macro_rules! bit_into_type {
($t:ty) => {
impl Into<$t> for Bit {
#![allow(clippy::from_over_into)]
fn into(self) -> $t {
match self {
Self::On => 1,
Self::Off => 0,
}
}
}
};
}
最后这是我用于
TryFrom
实现的宏:
macro_rules! bit_try_from {
($t:ty) => {
impl TryFrom<$t> for Bit {
type Error = String;
fn try_from(value: $t) -> Result<Self, Self::Error> {
match value {
0 => Ok(Bit::Off),
1 => Ok(Bit::On),
value => Err(format!("Cannot represent {} as a single bit", value)),
}
}
}
};
}
Enum::Variant as NumberType
检索变体的判别式。
如果没有显式分配判别式,则第一个变体分配为零,接下来的变体分配增加的判别式。
as f32/f64
获取整数判别式并将其转换为浮点数。