Как условно выполнить итерацию в обратном порядке?

Я хочу переключить направление итератора на основе логического параметра. Я попробовал следующий подход, но он заканчивается ошибкой компиляции:

fn main() {
    let numbers = vec![1, 2, 3, 4, 5, 6];

    print(&numbers, false);
    print(&numbers, true);
}

fn print(what: &[i32], reverse: bool) {
    let iter = what.iter();

    if reverse {
        iter = iter.rev();
    }

    for n in iter {
        println!("{n}");
    }
}

Это ошибка, которую я получаю:

// Error:
mismatched types
expected struct `std::slice::Iter<'_, _>`
   found struct `Rev<std::slice::Iter<'_, _>>`

Как я могу реализовать желаемое поведение?

Почему Python в конце концов умрет
Почему Python в конце концов умрет
Последние 20 лет были действительно хорошими для Python. Он прошел путь от "просто языка сценариев" до основного языка, используемого для написания...
1
0
86
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете сделать это с помощью динамической отправки, как описано здесь вот так:

fn iterateMyData(a: &mut VecDeque<A>, b: &mut BTreeMap<u64, VecDeque<B>>) {
    // Do something.

    let reverse: bool = a.front().unwrap().reverse;

    for a_value in a.iter_mut() {
        let mut temp_iter1;
        let mut temp_iter2;
        let mut iter: &mut dyn Iterator<Item = _> = if reverse {
            temp_iter1 = b.values_mut().rev();
            &mut temp_iter1
        } else {
            temp_iter2 = b.values_mut();
            &mut temp_iter2
        };
        
        for b_vec in iter {
            // Do something.
        }
    }
}

и ссылку на rustexplorer.

Однако, как уже отмечалось в связанной ветке выше, вероятно, проще и лучше использовать перечисление (ящик), например , либо вот так

let mut iter =
    if reverse { 
        Either::Left(b.values_mut().rev()) 
    }
    else { 
        Either::Right(b.values_mut()) 
    };

Также в случае, если вам просто нужно распечатать итератор в определенном направлении на основе флага, это можно сделать без внешних крейтов следующим образом:

fn main() {

    let numbers = vec![1, 2, 3, 4, 5, 6];

    print(&numbers, false);
    print(&numbers, true);
        
}

fn print(what: &[i32], reverse: bool) {
    //match statement condition check
    match reverse {
        true => {
            for n in what.iter().rev() {
                println!("{n}");
            }
        },
        false => {
            for n in what.iter() {
                println!("{n}");
            }
            
        },
    }
}

Другие вопросы по теме