gpt4 book ai didi

enums - 我最接近通过 char 区分枚举的是什么?

转载 作者:行者123 更新时间:2023-11-29 08:20:18 26 4
gpt4 key购买 nike

我已经把这个问题写了很多遍了,终于意识到我最大的问题是我不知道我想如何表示这些数据,这使得对其余代码的推理变得非常困难.

数据在 Python 中的表示方式:

class LSP():
C_MASK_MAP={
"A":"Ch A",
"B":"Ch B",
"C":"Ch C",
"D":"Ch D",
"T":"Tmpr",
"Y":"Batt",
"L":"Acc"
}

ADC_CHANS= (
"Ch A",
"Ch B",
"Ch C",
"Ch D",
"Tmpr",
"Batt"
)

ADC_MAJORS = (
"Ch A",
"Ch B",
"Ch C",
)

我想象中的 Rust 代码(我意识到名称需要更新,但为清楚起见,此处相同):

enum C_MASK_MAP {
Ch_A = 'A',
Ch_B = 'B',
Ch_C = 'C',
Ch_D = 'D',
Tmpr = 'T',
Batt = 'Y',
Acc = 'L'
}
//...
let ADC_CHANS = [
C_MASK_MAP::Ch_A,
C_MASK_MAP::Ch_B,
C_MASK_MAP::Ch_C,
C_MASK_MAP::Ch_D,
C_MASK_MAP::Tmpr,
C_MASK_MAP::Batt
];

ADC_MAJORS = [
C_MASK_MAP::Ch_A,
C_MASK_MAP::Ch_B,
C_MASK_MAP::Ch_C,
];

我考虑过制作 C_MASK_MAP一个HashMap<char, &'static str> , 但后来我遇到了一个巨大的困惑,试图不制作一百万份 str无处不在,处理生命周期,同时避免制造 String s,以及引用静态 str 的语法困惑(&&'static str 或其他东西)。

我认为能够使用枚举(或类似枚举)会有真正的好处,因为值不会那么大并且更容易互换 C_MASK_MAP.get(key).expect("invalid key") vs 只是类型转换。

最佳答案

您的字符串是标记值;这是 Python 中的一种常见模式,但在 Rust 中不应该这样做:枚举应该是这样的:你在类型系统中编码合法值。

你可能会得到这样的结果:

#[derive(Clone, Copy)]
#[repr(u8)]
pub enum Mask {
ChA = b'A',
ChB = b'B',
ChC = b'C',
ChD = b'D',
Tmpr = b'T',
Batt = b'Y',
Acc = b'L',
}

// e.g. Mask::ChA.into() == 'A'
impl Into<char> for Mask {
fn into(self) -> char {
self as u8 as char
}
}

impl Mask {
// e.g. Mask::from('A') == Ok(Mask::ChA)
pub fn from(c: char) -> Result<Mask, ()> {
match c {
'A' => Ok(Mask::ChA),
'B' => Ok(Mask::ChB),
'C' => Ok(Mask::ChC),
'D' => Ok(Mask::ChD),
'T' => Ok(Mask::Tmpr),
'Y' => Ok(Mask::Batt),
'L' => Ok(Mask::Acc),
_ => Err(()),
}
}

// e.g. Mask::ChA.is_chan() == true
pub fn is_chan(&self) -> bool {
match *self {
Mask::ChA | Mask::ChB | Mask::ChC | Mask::ChD | Mask::Tmpr | Mask::Batt => true,
Mask::Acc => false,
}
}

// e.g. Mask::ChD.is_major() == false
pub fn is_major(&self) -> bool {
match *self {
Mask::ChA | Mask::ChB | Mask::ChC => true,
Mask::ChD | Mask::Tmpr | Mask::Batt | Mask::Acc => false,
}
}
}

如果您愿意,您也可以为 Mask 实现 std::str::FromStr,这将允许 "A".parse() ==好的(掩码::ChA):

impl FromStr for Mask {
type Err = ();

fn from_str(s: &str) -> Result<Mask, ()> {
match s {
"A" => Ok(Mask::ChA),
"B" => Ok(Mask::ChB),
"C" => Ok(Mask::ChC),
"D" => Ok(Mask::ChD),
"T" => Ok(Mask::Tmpr),
"Y" => Ok(Mask::Batt),
"L" => Ok(Mask::Acc),
_ => Err(()),
}
}
}

我怀疑 is_chan 等人。可能比 ADC_CHANS 等更合适,但如果您确实需要它们,它们可以正常工作(您也可以使用 [Mask; 6],但如果您需要要添加新元素,它会更改类型,如果是公共(public)的,这会破坏 API 兼容性):

pub static ADC_CHANS: &'static [Mask] = &[
Mask::ChA,
Mask::ChB,
Mask::ChC,
Mask::ChD,
Mask::Tmpr,
Mask::Batt,
];

pub static ADC_MAJORS: &'static [Mask] = &[
Mask::ChA,
Mask::ChB,
Mask::ChC,
];

关于enums - 我最接近通过 char 区分枚举的是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54117433/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com