Home > database >  Rust nested for loop over two enums
Rust nested for loop over two enums

Time:12-02

I am trying to learn Rust and have defined two enums and a struct to implement a card deck:

use strum::IntoEnumIterator;
use strum_macros::EnumIter;

#[derive(Debug, EnumIter)]
enum Colors {
    Hearts,
    Spades,
    Diamonds,
    Clubs
}

#[derive(Debug, EnumIter)]
enum Numbers {
    Five,
    Six,
    Seven,
    Eight,
    Nine,
    Ten,
    Jack,
    Queen,
    King,
    Ace
}

struct Card {
    color : Colors,
    number : Numbers
}

When doing a loop over one of the enums it works as intended:

fn main() {
    for color in Colors::iter() {
       let card = Card {
            color: color,
            number: Numbers::Ace
        };
        println!("My card is a {:?} of {:?}", card.number, card.color);       
    }   
}

Output:

My card is a Ace of Hearts
My card is a Ace of Spades
My card is a Ace of Diamonds
My card is a Ace of Clubs

But when trying to nest two for loops as follows:

fn main() {
    for color in Colors::iter() {
        for number in Numbers::iter() {
            let card = Card {
                color: color,
                number: number
            };
            println!("My card is a {:?} of {:?}", card.number, card.color);       
        }
    }   
}

I get the compile error: error: use of moved value: 'color'

What am I doing wrong?

CodePudding user response:

Ok now found the issue after carefully reading the compiler error message ;-(

The inner loop moves color into the struct so after the first inner loop iteration color is not owner of the value anymore. Therefore color isn't available in the second iteration of the inner loop.

Solution was to implement the Clone trait for the Colors enum:

#[derive(Clone, Debug, EnumIter)]
enum Colors {
    Hearts,
    Spades,
    Diamonds,
    Clubs
}

and then move a clone of the color so owenership of the original value of the outer loop is not moved into the structure at any time.

    for color in Colors::iter() {
        for number in Numbers::iter() {
            let card = Card {
                color: color.clone(),
                number: number
            };
            println!("My card is a {:?} of {:?}", card.number, card.color);
        }
  • Related