Enums 有没有办法创建枚举值的别名?

Enums 有没有办法创建枚举值的别名?,enums,rust,alias,Enums,Rust,Alias,有没有办法做到这一点 enum MyType { Left, Right, #[cfg(universe = "normal")] Port = Left, #[cfg(universe = "normal")] Starboard = Right, #[cfg(universe = "mirror")] Port = Right, #[cfg(universe = "mirror")] Starboard =

有没有办法做到这一点

enum MyType {
    Left,
    Right,

    #[cfg(universe = "normal")]
    Port = Left,
    #[cfg(universe = "normal")]
    Starboard = Right,

    #[cfg(universe = "mirror")]
    Port = Right,
    #[cfg(universe = "mirror")]
    Starboard = Left,

}
如果您真的尝试过,就会出现这个错误(我必须添加
MyType::
):

error[E0080]:常量计算错误

-->就是触发错误的地方。

您的实现没有任何意义。请看一个更简单的版本:

enum MyType {
    One,
    Two = One,
}
另一种说法是:

enum MyType {
    One = 1,
    Two = 1,
}
您要求编译器创建两个相同的枚举变量,但枚举的全部要点是它们彼此排斥

而是创建一个常量(关联或其他):

据我所知不是这样

Rust中的枚举不像C中的枚举那样是“常量值束”。支持将数值与常量关联,但仅此而已。当然,可以创建任何名称的常量,但它们不允许模式匹配枚举值

从某种意义上说,枚举变量上的别名有点像类型字段上的别名。我从未见过任何由两个名称标识的单个字段出现;我想知道是否有任何语言支持它


我建议的解决方案是咬紧牙关,创建两个单独的枚举,并在它们之间进行转换:

use std::convert::From;

enum Side {
    Left,
    Right,
}

enum PortSide {
    Port,
    Starboard,
}

#[cfg(not(universe = "mirror"))]
impl From<Side> for PortSide {
    fn from(s: Side) -> PortSide {
        match s {
            Side::Left => PortSide::Port,
            Side::Right => PortSide::Starboard,
        }
    }
}

#[cfg(universe = "mirror")]
impl From<Side> for PortSide {
    fn from(s: Side) -> PortSide {
        match s {
            Side::Left => PortSide::Starboard,
            Side::Right => PortSide::Port,
        }
    }
}
使用std::convert::From;
枚举端{
左边
正确的,
}
枚举端口{
港口,
右舷
}
#[cfg(不是(universe=“mirror”)]
左舷的impl From{
fn从(s:侧)->左舷{
火柴{
Side::Left=>PortSide::Port,
舷侧::右侧=>左舷::右舷,
}
}
}
#[cfg(universe=“mirror”)]
左舷的impl From{
fn从(s:侧)->左舷{
火柴{
左舷=>左舷::右舷,
Side::Right=>PortSide::Port,
}
}
}

另外,我建议您不要要求指定某个特性,而是允许在没有该特性的情况下使用默认行为。在您的情况下,“normal”似乎应该是默认行为。

您可以使用关联的常量来获取与枚举变量非常相似的常量:

#[derive(PartialEq, Eq)]
pub enum X {
    A,
    B,
}

impl X {
    pub const A1: X = X::A;
}
与普通变量一样,关联的常量在枚举中具有名称空间。它与模式匹配兼容-即使是无法到达的警告和详尽的匹配规则也可以工作

match x {
    X::A1 => ...,
    X::B => ...,
}


有一些限制:最重要的是,您不能有任何与该值关联的数据。您还需要在结构上
#[派生(PartialEq,Eq)]

是的,我正在尝试创建别名。Rust已经有了类型别名,没有问题。你能举个例子,说明支持枚举变量别名会破坏一些东西,因为我看不到任何东西。@timmm:问题是模式匹配。如果你有
匹配x{One=>{},Two=>{}}
,你会选择哪个手臂?这不是问题。它的行为就像您编写了
匹配x{One=>{},One=>{}
,即打印一个错误。(它实际打印的错误是
这是一个无法访问的模式
)我正在考虑推荐一个辅助枚举。似乎有时需要一种表示法或另一种表示法,但不能同时使用这两种表示法。C“支持”通过预处理器使用enum和struct字段别名。这里我只是半开玩笑-典型的Unix实现,例如
struct stat
经常使用此功能,这也是为什么在struct和union字段前面加前缀的一部分原因(另一部分是它保护标准库不受应用程序的影响#定义与struct字段匹配的内容)。
match x {
    X::A1 => ...,
    X::B => ...,
}