【问题标题】:Can enum variants have constant associated values? [duplicate]枚举变体可以具有恒定的关联值吗? [复制]
【发布时间】:2020-07-06 15:14:29
【问题描述】:

我有代码 (playground):

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.
}

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

一个枚举可以用来改善这个,比如:

enum Items {
    A = SomeStruct { x: 2., y: 2 },
    B = SomeStruct { x: 3.5, y: 1 },
    C = SomeStruct { x: 0., y: 5 },
}

这实际上是一个const 枚举,这样当将来引用这些项目时,我们可以简单地使用Items::A&amp;Items::A 而不是'a',并且必须进行必要的哈希处理。

看来这样做是不可行的。

有没有办法使用const enum?还是有其他更好的解决方案?

虽然这个问题可能与How can I create enums with constant values in Rust? 重复,但在使用任意结构时,根据该问题提出的解决方案不起作用。 solution vallentin added 确实如此,但此解决方案确实更适用于其他解决方案不起作用的情况。我认为它在这个问题的上下文中提供了一个更好更清晰的答案,而其他更简单的解决方案不起作用。

【问题讨论】:

标签: enums rust constants


【解决方案1】:

您可以使用associated constants, 这类似于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 };
}

或者,如果您使用 Nightly,您可以使用 const_if_match 在 const 方法中进行匹配。这也是lately stabilized

#![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 },
        }
    }
}

【讨论】:

  • 我鼓励您将您的答案移至重复的问题,因为这将是其他答案中独一无二的解决方案。
  • #![feature(const_if_match)] 已稳定,因此不再需要在夜间使用该属性。它将进入下一个测试版和下一个稳定版。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多