我想创建一个由枚举中的元素指定的大小的数组,如下所示:
pub use self::Register::*;
enum Register {
Ip,
Sp,
NumRegs,
}
struct State {
val: int,
regs: [int; NumRegs as int],
running: bool,
}
但我明白了:
src/main.rs:19:11: 19:32 error: expected constant expr for array length: non-constant path in constant expr
src/main.rs:19 regs: [int; NumRegs as int],
我尝试过使用as int
以及其他解决方案,并且谷歌搜索了一段时间,但还没有找到解决方案。顺便说一句,这是Rust中的错误形式吗?
答案 0 :(得分:2)
目前,我不认为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
的调用)。