我最接近用char区分枚举的是什么? [英] What's the closest I can get to discriminating an enum by a char?
问题描述
我已经写了很多遍这个问题,终于意识到我最大的问题是我不知道如何表示这些数据,这使得很难推理其余的代码。
I've written this question out many times, and have finally realized that my biggest problem is that I don't know how I want to represent this data, and that's making it really hard to reason about the rest of the code.
在Python中表示数据的方式:
The way the data is represented in 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代码(我知道名称需要更新,但是为了清楚起见,在这里是相同的):
My imaginary Rust code (I realize the names will need updating but are the same here for clarity):
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
a HashMap< char,&'static str>
,但是后来我陷入混乱,试图不制作一百万个 str
s无处不在,并处理生命周期,同时避免使用 String
s,以及避免引用静态 str $的语法混乱c $ c>(
&''static str
之类的东西)。
I've considered making C_MASK_MAP
a HashMap<char, &'static str>
, but then I ran into a huge mess trying not to make a million copies of the str
s everywhere and dealing with lifetimes while avoiding making String
s, and the syntactic mess that is a reference to a static str
(&&'static str
or something).
我认为使用枚举(或类似枚举)的真正好处是,值不会那么大,并且更容易互换 C_MASK_MAP.get(key).expect( invalid key)
I think there'd be a real benefit to being able to use an enum (or similar) because the values wouldn't be as big and are more easily interchanged C_MASK_MAP.get(key).expect("invalid key")
vs just casting.
推荐答案
您的字符串是前哨值;这是Python中的一种常见模式,但是在Rust中却不是这样:枚举就是这样:您正在类型系统中编码合法值。
Your strings are sentinel values; this is a common pattern in Python, but is not how things should be done in Rust: enums are what such things should be: you’re encoding the legal values in the type system.
您最终可能会遇到这样的情况:
You could end up with something like this:
#[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()== Ok(Mask :: ChA)
:
If you wanted you could implement std::str::FromStr
for Mask
as well, which would allow "A".parse() == Ok(Mask::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]
,但是如果您需要添加新元素,则会更改类型,如果公开的话,这是API兼容性中断):
I suspect that is_chan
et al. may be more suitable than ADC_CHANS
et al., but if you do actually need them, they work fine (you could do [Mask; 6]
too, but if you need to add new elements it’d change the type which is an API compatibility break if public):
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,
];
这篇关于我最接近用char区分枚举的是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!