在 Rust 中实现枚举的通用特征

Implementing Generic Trait for Enum in Rust

有没有办法为枚举实现具有通用类型 T 的特征?像这样:

use rand::thread_rng;
use rand::seq::SliceRandom;

pub enum Color {
    Red,
    Blue,
    Green,
}

trait Shuffable {
    fn values<T>() -> Vec<T>;

    fn shuffled<T: Shuffable>() -> Vec<T> {
        let mut items = T::values();
        items.shuffle(&mut thread_rng());

        items
    }
}

impl Shuffable for Color {
    fn values<Color>() -> Vec<Color> {
        vec![Color::Red, Color::Blue, Color::Green]
    }
}

此错误是因为无法将枚举项与类型本身相关联

error[E0599]: no associated item named `Red` found for type parameter `Color` in the current scope
  --> src/game.rs:25:21
   |
25 |         vec![Color::Red, Color::Blue, Color::Green]
   |                     ^^^ associated item not found in `Color`

error[E0599]: no associated item named `Blue` found for type parameter `Color` in the current scope
  --> src/game.rs:25:33
   |
25 |         vec![Color::Red, Color::Blue, Color::Green]
   |                                 ^^^^ associated item not found in `Color`

error[E0599]: no associated item named `Green` found for type parameter `Color` in the current scope
  --> src/game.rs:25:46
   |
25 |         vec![Color::Red, Color::Blue, Color::Green]
   |                                              ^^^^^ associated item not found in `Color`

我已经检查了https://github.com/rust-lang/rust/issues/52118,但似乎没有关系!

作为起点,我们可以让您的代码按如下方式工作:

use rand::thread_rng;
use rand::seq::SliceRandom;

#[derive(Debug)]
pub enum Color {
    Red,
    Blue,
    Green,
}

trait Shuffable where Self: Sized {
    fn values() -> Vec<Self>;
    fn shuffled() -> Vec<Self> {
        let mut items = Self::values();
        items.shuffle(&mut thread_rng());
        items
    }
}

impl Shuffable for Color {
    fn values() -> Vec<Self> {
        vec![Color::Red, Color::Blue, Color::Green]
    }   
}

fn main() {
    let shuffled = Color::shuffled();
    println!("{:?}", shuffled)
}

Self 必须调整大小,因为实现 Shuffable 的具体类型需要存储在向量中,我们需要知道我们分配了多少 space。

我认为混淆点可能与泛型参数 T 有关,我假设您认为这是代表 Color 类型?如果是这样,这不是必需的,因为您正在为其实现特征的类型是通过 Self 表示的。 T 引入了另一种不受任何限制的类型。