创建一个具有枚举元素大小的数组
Create an array with enum element size
我想创建一个大小由枚举中的元素指定的数组,如下所示:
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
,以及其他解决方案,并在 Google 上搜索了一段时间,但没有找到解决方案。顺便说一句,这种形式在 Rust 中是错误的吗?
目前,我不认为 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
的调用).
我想创建一个大小由枚举中的元素指定的数组,如下所示:
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
,以及其他解决方案,并在 Google 上搜索了一段时间,但没有找到解决方案。顺便说一句,这种形式在 Rust 中是错误的吗?
目前,我不认为 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
的调用).