代码之家  ›  专栏  ›  技术社区  ›  Jared Smith

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

  •  0
  • Jared Smith  · 技术社区  · 1 年前

    例如,我们有两个枚举,代表一副标准扑克牌的等级和花色:

    #[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 }
    

    然而,枚举不实现迭代器,这是有道理的,因为枚举可以包含任意数据类型,包括需要参数/构造的数据类型和不需要的数据类型 能够 实现Iterator特性,或者我可以实现 TryFrom 使用整数元组和do for i in 0..4 { for j in 0..13 { 或者,如果我费心的话,我可能会想到其他一些事情,问题标题中提到的问题是,AFAIK所有这些解决方案都需要我在实现中手动键入所有52个变体。

    我知道静态枚举有几种可迭代枚举宏的实现,有没有其他方法可以做到这一点,而无需全部键入或使用过程宏?或者,我只是以这种方式对一副牌进行了完全偏离基础的建模?

    0 回复  |  直到 1 年前
        1
  •  4
  •   Kevin Reid    1 年前

    如前所述,有很多方法可以生成枚举迭代器,但您可能对我的库感兴趣 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 }
    ...