例如,我们有两个枚举,代表一副标准扑克牌的 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 个变体。
我知道有几种用于静态枚举的可迭代枚举宏的实现,是否有其他方法可以简单地做到这一点,而无需将它们全部输入或使用过程宏?或者我用这种方式建模一副纸牌完全是错误的吗?
正如已经链接的那样,有很多方法可以生成枚举迭代器,但您可能对我的库感兴趣
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 }
...