В настоящее время я не думаю, что Руст способен видеть, что 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,
};
}
Edit
Если вы хотите, чтобы получить реестр по имени, как насчет мы делаем это непосредственно:
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
).
'enum' не семантически соответствует числовому значению, как вы могли бы ожидать, если бы вы пришли из C. Не могли бы вы объяснить немного больше о том, какой код вы действительно хотели бы иметь? – Shepmaster