可以在枚举类型上使用特征吗?

Ver*_*gil 6 enums traits rust

我通读了trait文档,发现了在结构上使用trait的简洁定义。是否可以在enum类型上使用特征?我已经看到回答说“不”的答案,但是他们已经3岁了,还没有完全按照我的意愿去做。

我试图这样做:

#[derive(Debug, Copy, Clone)]
pub enum SceneType {
    Cutscene,
    Game,
    Menu,
    Pause,
    Credits,
    Exit,
}

//We want to guarantee every SceneType can be played statically
trait Playable {
    fn play();
}

impl Playable for SceneType::Cutscene {
    fn play() {}
}
Run Code Online (Sandbox Code Playgroud)
#[derive(Debug, Copy, Clone)]
pub enum SceneType {
    Cutscene,
    Game,
    Menu,
    Pause,
    Credits,
    Exit,
}

//We want to guarantee every SceneType can be played statically
trait Playable {
    fn play();
}

impl Playable for SceneType::Cutscene {
    fn play() {}
}
Run Code Online (Sandbox Code Playgroud)

我不明白此错误,因为它引用的枚举位于同一文件中。如果我真的不能在枚举变量上使用特征,是否有什么方法可以保证任何枚举特征必须实现某些方法?

She*_*ter 8

可以在枚举类型上使用特征吗?

是的。实际上,您已经为枚举定义了多个特征。特征DebugCopy以及Clone

#[derive(Debug, Copy, Clone)]
pub enum SceneType
Run Code Online (Sandbox Code Playgroud)

问题是您没有尝试Playable为您的枚举实现,而是尝试为枚举的变体之一实现它。枚举变量不是类型

如错误消息告诉您:

#[derive(Debug, Copy, Clone)]
pub enum SceneType
Run Code Online (Sandbox Code Playgroud)
impl Playable for SceneType {
    fn play() {}
}
Run Code Online (Sandbox Code Playgroud)

也可以看看:

  • 但如果我想为所有枚举变体(Cutscene.play()、Game.play() 等)实现 Playable,我应该做什么?将 `match` 表达式添加到 SceneType.play() 方法? (8认同)
  • 这种语言是不是很奇怪,因为它允许枚举不同的数据类型。因此,不允许枚举上有特征有点违反直觉。想法? (4认同)
  • @rusnasonov 是的。 (2认同)

Sil*_*olo 5

如果你想实现一个特征Playable(即所有枚举变体),那么答案很简单:是的,你可以。Shepmaster 的答案详细说明了如何做到这一点。

但是,如果您确实只想要一个枚举变体Playable而不是其他枚举变体,那么 Rust 并不直接支持这一点,但我见过一种用来模拟它的习惯用法。代替

enum MyEnum {
  A(i32, i32),
  B(String),
}
Run Code Online (Sandbox Code Playgroud)

您将每个枚举变体显式实现为单独的结构,因此

enum MyEnum {
  A(A),
  B(B),
}

struct A {
  x: i32,
  y: i32,
}

struct B {
  name: String,
}
Run Code Online (Sandbox Code Playgroud)

然后你就可以impl Playable for A不用impl Playable for B. 每当你想调用它时,模式匹配MyEnum,如果你得到一个A,你可以play在你的例子中调用模式匹配的结果。

我不建议对您编写的每个枚举都使用此模式,因为它确实使代码变得更加冗长,并且需要一些样板构造函数方法才能使其易于接受。但对于具有很多选项的复杂枚举,这种模式可以使代码更容易推理,特别是如果您有很多仅真正适用于几种枚举可能性的特征或函数。