arrays - 创建一个具有枚举元素大小的数组

标签 arrays enums rust

我想创建一个由枚举中的元素指定大小的数组,如下所示:

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 )。

关于arrays - 创建一个具有枚举元素大小的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27865837/

相关文章:

rust - 如何在立即丢弃向量时将值移出向量?

rust - 在Rust中挣扎着悬而未决的引用和静态生命周期建议

javascript - 获取多选下拉框的选定元素

c - 学习c编程——将数组传递给函数

php - "Notice: Undefined variable"、 "Notice: Undefined index"、 "Warning: Undefined array key"和 "Notice: Undefined offset"使用 PHP

java - 语法错误 : insert "enum Identifier", 插入 "EnumBody",插入 "}"

rust - 特征边界 `futures::Future<Item=Arc<T>, Error=Box<Error + Send>>: Send` 不满足

javascript - CoffeeScript:如何从类中返回一个数组?

C#:枚举值可以保存为设置吗?

java - Optaplanner/Drools 在solverFactory.buildSolver() 中抛出异常