Enums 如何返回特定索引处的枚举字符串?

Enums 如何返回特定索引处的枚举字符串?,enums,rust,Enums,Rust,实现这一目标最简单的方法是什么 enum E { A, B, C, } // Should return "A" for 0, "B" for 1 and "C" for 2 fn convert(i: u32) -> str { // ??? } 有必要添加[deriveDebug]属性并在枚举上定义一个实现: #[derive(Debug)] #[derive(Copy, Clone)] enum E { A, B, C, }

实现这一目标最简单的方法是什么

enum E {
    A,
    B,
    C,
}

// Should return "A" for 0, "B" for 1 and "C" for 2
fn convert(i: u32) -> str {
    // ???
}

有必要添加[deriveDebug]属性并在枚举上定义一个实现:

#[derive(Debug)]
#[derive(Copy, Clone)]
enum E {
    A,
    B,
    C,
}

impl E {
    fn from(t: u8) -> E {
        assert(t<=enum_to_int(E::C), "Enum range check failed!");
        let el: E = unsafe { std::mem::transmute(t) };
        return el;
    }
    fn to_string(&self) -> String {
        return format!("{:?}", self);
    }

    fn string_from_int(t: u8) -> String {
        return E::from(t).to_string();
    }
}


fn enum_to_int(el: &E) -> u8 {
    *el as u8
}
您不能返回str,但可以返回(&str)。将来自和的想法结合起来:


相关:它永远无法返回str,因为它没有大小。它需要是String或&str。不要像这样使用transmute!这是非常不安全的,可能会导致不明确的行为。Rust中的枚举与C中的枚举不同:它们不能具有未由编译器定义的标记值。如果您不完全理解Rust中关于不安全编码的规则,您就不应该使用不安全代码。@2080如果t超出范围,这将爆炸。您最好使用match语句并处理每种情况。或者,您可以让宏首先生成枚举,同时创建to_str方法。为什么会被否决?它可以工作并回答我的问题。不能保证枚举的表示从0开始。此外,您正在执行无边界检查。这不会导致一个很好的错误-甚至可能不会引起恐慌-它会导致未定义的行为。这是不安全的,不应该使用。值得注意的是,segfault是被触发的,因为正如@PeterHall所提到的,如果你出界,不安全的人不会在意,你告诉他什么就做什么。这就是触发segfault的原因:3是越界的,这里,假设的边界是[0,2]。由于这种类型的强制转换对于所有[reprRust]枚举都是UB的,所以只有“幸运”的话,它才能在绑定时工作——生锈并不能保证这一点。然而,对于类[reprC]C的枚举来说,这是有保证的行为,但这将是可怕的、脆弱的代码,以及糟糕的、糟糕的实践。匹配是一种方法,或@Shepmaster的答案。将[repru8]添加到枚举中,并将3更改为2,以使转换调用不会超出范围,这是使此答案正确的最低要求。使其安全是另一个问题,但是您可以通过from函数中的范围检查来做到这一点。
fn main() {
    let s = E::string_from_int(3 as u8);
    println!("{}", s);
}
#[macro_use]
extern crate strum_macros;
extern crate strum;

use strum::IntoEnumIterator;

#[derive(EnumIter, AsRefStr)]
enum E {
    A,
    B,
    C,
}

fn main() {
    let e = E::iter().nth(2);
    assert_eq!(e.as_ref().map(|e| e.as_ref()), Some("C"));
}