在 Rust 中获取两个枚举的叉积,而无需将它们全部键入

问题描述 投票:0回答:1

例如,我们有两个枚举,代表一副标准扑克牌的 Rank 和 Suit:

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
enum Suit {
    Spades,
    Hearts,
    Diamonds,
    Clubs,
}

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
enum Rank {
    Two,
    Three,
    Four,
    Five,
    Six,
    Seven,
    Eight,
    Nine,
    Ten,
    Jack,
    Queen,
    King,
    Ace,
}

枚举是有效有界的值集,如果有人希望构建所有可能对的完整一副,我们可以将其建模为两者的笛卡尔积。用命令式的术语来说,人们可以想象类似的东西

for suit in Suit {
  for rank in Rank {
    Card { suit, rank }

但是枚举不实现迭代器,这是有道理的,因为枚举可以包含任意数据类型,包括需要参数/构造的数据类型和不需要参数/构造的数据类型。我可以实现迭代器特征,或者我可以用整数元组实现

TryFrom
并执行
for i in 0..4 { for j in 0..13 {
或者如果我打扰的话我可能会想到其他一些事情,问题标题中所述的问题是AFAIK 所有这些解决方案都需要我在实现中手动输入所有 52 个变体。

我知道有几种用于静态枚举的可迭代枚举宏的实现,是否有其他方法可以简单地做到这一点,而无需将它们全部输入或使用过程宏?或者我用这种方式建模一副纸牌完全是错误的吗?

rust enums cartesian-product
1个回答
0
投票

正如已经链接的那样,有很多方法可以生成枚举迭代器,但您可能对我的库感兴趣

exhaust
,它还可以为结构(以及枚举变体中的字段值)生成笛卡尔积迭代器,但这不适用于这种情况):

use exhaust::Exhaust;

#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Exhaust)]
enum Suit {
    Spades,
    Hearts,
    Diamonds,
    Clubs,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Exhaust)]
enum Rank {
    Two,
    Three,
    Four,
    Five,
    Six,
    Seven,
    Eight,
    Nine,
    Ten,
    Jack,
    Queen,
    King,
    Ace,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, Exhaust)]
struct Card {
    rank: Rank,
    suit: Suit,
}

fn main() {
    for c in Card::exhaust() {
        println!("{c:?}");
    }
}

打印:

Card { rank: Two, suit: Spades }
Card { rank: Two, suit: Hearts }
Card { rank: Two, suit: Diamonds }
Card { rank: Two, suit: Clubs }
Card { rank: Three, suit: Spades }
Card { rank: Three, suit: Hearts }
Card { rank: Three, suit: Diamonds }
Card { rank: Three, suit: Clubs }
Card { rank: Four, suit: Spades }
Card { rank: Four, suit: Hearts }
...
© www.soinside.com 2019 - 2024. All rights reserved.