目前,我不认为 Rust 能够看到 Enum::Variant 实际上是一个常量(我实际上也不知道它是),所以它不能用作数组长度。不仅如此,我会说添加一个实际上并不打算使用的枚举变体很奇怪。
对于我如何看待您的问题,我可能会尝试将您的寄存器表示为结构:
struct Registers {
ip: u8,
sp: u8,
}
struct State {
val: u8,
regs: Registers,
running: bool,
}
fn main() {
let s = State {
val: 0,
regs: Registers { ip: 0, sp: 0 },
running: false,
};
}
编辑
如果您想按姓名注册,我们直接这样做怎么样:
struct Registers {
ip: u8,
sp: u8,
}
impl Registers {
fn by_name(&self, name: &str) -> u8 {
match name {
"ip" => self.ip,
"sp" => self.sp,
_ => panic!("Unknown register '{}'", name),
}
}
fn by_name_mut(&mut self, name: &str) -> &mut u8 {
match name {
"ip" => &mut self.ip,
"sp" => &mut self.sp,
_ => panic!("Unknown register '{}'", name),
}
}
}
fn main() {
let mut r = Registers { ip: 0, sp: 0 };
println!("Instruction pointer: 0x{:02x}", r.by_name("ip"));
*r.by_name_mut("ip") += 1;
println!("Instruction pointer: 0x{:02x}", r.by_name("ip"));
}
虽然panic! 确实很丑……但我宁愿为此目的使用枚举。让我们同时做枚举和字符串:
use std::str::FromStr;
#[derive(Debug,Copy,Clone,PartialEq)]
enum Register {
Ip,
Sp,
}
impl FromStr for Register {
type Err = ();
fn from_str(s: &str) -> Result<Self, ()> {
match s {
"ip" => Ok(Register::Ip),
"sp" => Ok(Register::Sp),
_ => Err(()),
}
}
}
struct Registers {
ip: u8,
sp: u8,
}
impl Registers {
fn by_name(&self, name: Register) -> u8 {
match name {
Register::Ip => self.ip,
Register::Sp => self.sp,
}
}
fn by_name_mut(&mut self, name: Register) -> &mut u8 {
match name {
Register::Ip => &mut self.ip,
Register::Sp => &mut self.sp,
}
}
}
fn main() {
let mut rs = Registers { ip: 0, sp: 0 };
let r: Register = "ip".parse().unwrap();
println!("Instruction pointer: 0x{:02x}", rs.by_name(r));
*rs.by_name_mut(r) += 1;
println!("Instruction pointer: 0x{:02x}", rs.by_name(r));
}
现在我们在将字符串转换为 Register 类型之间有一个很好的清晰分离,这意味着我们的代码只有一部分必须处理无效的寄存器名称(对 unwrap 的调用)。