枚举变体可以具有恒定的关联值吗?

Jon*_*ght 4 enums constants rust

我有代码(游乐场):

use std::collections::HashMap;

// We have some arbitrary struct (given values just placeholders)
struct SomeStruct {
    x: f32,
    y: usize,
}

fn main() {
    // We have some hashmap which contains the names (keys) and properties (values) of items.
    //  These are known at compile time.
    let hashmap: HashMap<&str, SomeStruct> = vec![
        ("a", SomeStruct { x: 2., y: 2 }),
        ("b", SomeStruct { x: 3.5, y: 1 }),
        ("c", SomeStruct { x: 0., y: 5 }),
    ]
    .into_iter()
    .collect();

    // We then have a bunch of data which arbitrarily references the names of these items.
    //  This data is also known at compile time.
}
Run Code Online (Sandbox Code Playgroud)

当需要引用项目时不断地输入"a"、等是不好的。"b"

可以使用枚举来改善这一点,例如:

enum Items {
    A = SomeStruct { x: 2., y: 2 },
    B = SomeStruct { x: 3.5, y: 1 },
    C = SomeStruct { x: 0., y: 5 },
}
Run Code Online (Sandbox Code Playgroud)

这实际上是一个const枚举,这样当将来引用这些项目时,我们可以简单地执行Items::A&Items::A而不是'a'必须执行必要的散列。

看来这样做是行不通的。

有没有办法使用 a const enum?或者有其他更好的解决方案吗?

虽然这个问题可能与How can I create enums with Constant Values in Rust?重复。使用任意结构时,该问题下提出的解决方案不起作用。vallentin 添加的解决方案确实有效,但该解决方案实际上更适用于其他解决方案不起作用的情况。我认为它在这个问题的背景下提供了一个更好更清晰的答案,而其他更简单的解决方案不起作用。

Val*_*tin 8

您可以使用关联的常量,这类似于bitflags crate 的工作方式。如果添加#[non_exhaustive]Items,则可以阻止 的实例化Items

#[non_exhaustive]
struct Items;

impl Items {
    pub const A: SomeStruct = SomeStruct { x: 2., y: 2 };
    pub const B: SomeStruct = SomeStruct { x: 3.5, y: 1 };
    pub const C: SomeStruct = SomeStruct { x: 0., y: 5 };
}
Run Code Online (Sandbox Code Playgroud)

或者,如果您使用 Nightly,则可以使用 const 方法进行匹配const_if_match。最近也趋于稳定

#![feature(const_if_match)]

enum Items {
    A,
    B,
    C,
}

impl Items {
    const fn value(self) -> SomeStruct {
        use Items::*;
        match self {
            A => SomeStruct { x: 2.0, y: 2 },
            B => SomeStruct { x: 3.5, y: 1 },
            C => SomeStruct { x: 0., y: 5 },
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我鼓励您将答案移至重复的问题,因为这将是其他答案中唯一的解决方案。 (3认同)