迭代实现自定义特征的枚举

发布于 2025-01-25 19:31:20 字数 2277 浏览 2 评论 0原文

我遇到了Rust的问题,我想迭代实现自定义特征的隔板矢量。

我的自定义特征:

pub trait PieceFeature
    {
        fn acronym(&self) -> &str;
        fn name(&self) -> &str;
        fn color(&self) -> ConsoleColor;
        fn to_vec_box() -> Vec<Box<Self>> where Self: Sized;
    }

我有两个枚举,第一个是颜色,它实现了priectfeature性状和显示特质:

#[derive(Debug, Clone, PartialEq, IntoEnumIterator)]
    pub enum Color {
        White,
        Dark,
    }

    impl PieceFeature for Color {
        fn acronym(&self) -> &str {
            match self {
                Self::White => "W",
                Self::Dark => "D",
            }
        }

        fn name(&self) -> &str {
            match self {
                Self::White => "White",
                Self::Dark => "Dark"
            }
        }

        fn color(&self) -> ConsoleColor {
            ConsoleColor::Blue
        }

        fn to_vec_box() -> Vec<Box<Color>> {
            vec![Box::new(Color::White), Box::new(Color::Dark)]
        }        
    }
    impl Display for Color {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            write!(f, "{}", self.color().paint(self.acronym()))
        }
    }

我得到了第二个(高度),它做得完全相同(我不编写实现,但

 #[derive(Debug, Clone, PartialEq, IntoEnumIterator)]
    pub enum Height {
        Small,
        Tall,
    }

现在 完全是以前的)我想动态循环循环我的枚举,以在控制台应用程序中显示传奇。 我尝试了一些东西,但它无法按照我的意愿起作用。 这是我的新手代码,有效:

let pieces_feature: Vec<Box<dyn PieceFeature>> = vec![
            Box::new(Color::Dark),
            Box::new(Color::White),
            Box::new(Height::Small),
            Box::new(Height::Tall),
        ];`
         // some code ...
         //Draw legend
         for (i, e) in pieces_feature.into_iter().enumerate() {
            legend = format!("{} \t {}: {}", legend, e.color().paint(e.acronym()), e.name());
        }
        //....

我的代码有效,但我不满意不动态构建我的“ picts_feature”向量。 如您所见,我尝试实现一个自定义函数“ to_vec_box()”,但是我有一个错误,上面说vec&lt; box&lt; self&gt;&gt;&gt;vec&lt; box&lt; dyn prieffeature&gt;。 实现这一目标的最佳方法是什么?

I got a problem with Rust, I want to iterate over a vector of severals enum which implement a custom traits.

My custom trait:

pub trait PieceFeature
    {
        fn acronym(&self) -> &str;
        fn name(&self) -> &str;
        fn color(&self) -> ConsoleColor;
        fn to_vec_box() -> Vec<Box<Self>> where Self: Sized;
    }

I got two enums, the first is Color which implement PieceFeature trait and Display trait :

#[derive(Debug, Clone, PartialEq, IntoEnumIterator)]
    pub enum Color {
        White,
        Dark,
    }

    impl PieceFeature for Color {
        fn acronym(&self) -> &str {
            match self {
                Self::White => "W",
                Self::Dark => "D",
            }
        }

        fn name(&self) -> &str {
            match self {
                Self::White => "White",
                Self::Dark => "Dark"
            }
        }

        fn color(&self) -> ConsoleColor {
            ConsoleColor::Blue
        }

        fn to_vec_box() -> Vec<Box<Color>> {
            vec![Box::new(Color::White), Box::new(Color::Dark)]
        }        
    }
    impl Display for Color {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            write!(f, "{}", self.color().paint(self.acronym()))
        }
    }

And I got a second (Height) which do exactly the same (I don't write the implementation, but it's exactly as previous)

 #[derive(Debug, Clone, PartialEq, IntoEnumIterator)]
    pub enum Height {
        Small,
        Tall,
    }

Now I want to dynamically loop over my enum to display a legend in my console application.
I tried severals things but it doesn't work as I want.
Here is my newbie code which work :

let pieces_feature: Vec<Box<dyn PieceFeature>> = vec![
            Box::new(Color::Dark),
            Box::new(Color::White),
            Box::new(Height::Small),
            Box::new(Height::Tall),
        ];`
         // some code ...
         //Draw legend
         for (i, e) in pieces_feature.into_iter().enumerate() {
            legend = format!("{} \t {}: {}", legend, e.color().paint(e.acronym()), e.name());
        }
        //....

My code works, but I'm not happy to not dynamically build my "pieces_feature" vector.
As you can see, I tried to implement a custom function "to_vec_box()" but I got a error which says that Vec<Box<Self>> is not the same as Vec<Box<dyn PieceFeature>>.
What is the best way to achieve this ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你曾走过我的故事 2025-02-01 19:31:20

您有几个选择,例如:

  1. 将类型更改为方法本身中真正想要的内容(请注意,您还必须更改特质方法签名):
fn to_vec_box() -> Vec<Box<dyn PieceFeature>> {
    vec![Box::new(Color::White), Box::new(Color::Dark)]
}
  1. 在更改迭代类型的同时对它们进行迭代:
let features = Color::to_vec_box()
    .into_iter()
    .map(|p| p as Box<dyn PieceFeature>)
    .chain(Height::to_vec_box()
        .into_iter()
        .map(|p| p as Box<dyn PieceFeature>)
    );

for feature in features {
    ...
}

You have a few options, like:

  1. Change your types to what you really want in the method itself (notice you would have to change also the trait method signature):
fn to_vec_box() -> Vec<Box<dyn PieceFeature>> {
    vec![Box::new(Color::White), Box::new(Color::Dark)]
}
  1. Iterate over them while changing the types on iteration:
let features = Color::to_vec_box()
    .into_iter()
    .map(|p| p as Box<dyn PieceFeature>)
    .chain(Height::to_vec_box()
        .into_iter()
        .map(|p| p as Box<dyn PieceFeature>)
    );

for feature in features {
    ...
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文