“as”运算符如何将枚举转换为整数?

问题描述 投票:0回答:1

我正在为我的一个项目创建一个 Bit 枚举,并且我经历了与

as u32
(或任何其他类型)语法的一些奇怪的交互。我已经为我的 Bit 枚举实现了 Into,所以我在我的测试中无意中使用了
Bit 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,并将所有其他值映射到错误。

通常我会查看此文档,但我不知道在哪里可以专门找到此文档,因为它更多的是一种语言功能而不是某个东西的实现,指向它的指针也有帮助!

游乐场链接:https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=c06998e915b2b4aa44d58ec67d21eabb

作为参考,这是我使用

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)),
                }
            }
        }
    };
}
rust enums
1个回答
0
投票

Enum::Variant as NumberType
检索变体的判别式

如果没有显式分配判别式,则第一个变体分配为零,接下来的变体分配增加的判别式

as f32/f64
获取整数判别式并将其转换为浮点数。

© www.soinside.com 2019 - 2024. All rights reserved.