«временное значение отбрасывается при заимствовании» при создании итератора на основе условия

Я пытаюсь создать Iterator в Rust, который возвращает значения и индексы ненулевых элементов в массиве. Это Iterator должно быть обратимым на основе параметра bool.

Мне удалось построить Iterator без условия обратный:

fn main() {
    let arr: [u8; 8] = [0, 2, 0, 0, 0, 1, 0, 5];

    for (i, x) in arr.iter().enumerate().filter(|(_, &x)| x!=0) {
        println!("index: {}, value: {}", i, x);
    }
}

>>> index: 1, value: 2
>>> index: 5, value: 1
>>> index: 7, value: 5

Однако при попытке построить Iterator на основе логического условия (на основе эта почта) я получаю сообщение об ошибке при компиляции: временное значение упало при заимствовании рассмотрите возможность использования привязки let для создания более долговечной ценности rustc(E0716).

fn main() {
    // Array to observe
    let arr: [u8; 8] = [0, 2, 0, 0, 0, 1, 0, 5];
    // Reverse parameter
    let reverse: bool = true;

    // Building Iterator based on `reverse` parameter
    let iter: &mut dyn Iterator<Item = (usize, &u8)> = match reverse {
        // forward Iterator
        false => {
            &mut arr.iter().enumerate().filter(|(_, &x)| x!=0)
        }
        // Reversed iterator
        true => {
            &mut arr.iter().enumerate().filter(|(_, &x)| x!=0).rev()
        }
    };

    // Print indices and values of non 0 elements in the array
    for (i, x) in iter {
        println!("index: {}, value: {}", i, x);
    }
}

Я попытался клонировать массив или объявить Iterator с ключевым словом let, как было предложено компилятором, но ничего из этого не сработало. Есть идеи?

Вы можете решить эту проблему, объявив переменные для хранения временных объектов за пределами оператора match, так же, как здесь: детская площадка.

Caesar 13.05.2022 03:52
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
0
1
52
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Проблема в вашем коде в том, что вы берете ссылку на временную переменную.

При попытке исправить это вам придется обойти несколько других проблем, связанных с итераторами, например, использование rev() для изменения его типа.

Я думаю, что ваш код лучше всего написать примерно так:

use std::fmt::Display;

fn main() {
    // Array to observe
    let arr: [u8; 8] = [0, 2, 0, 0, 0, 1, 0, 5];
    // Reverse parameter
    let reverse: bool = true;

    // Building Iterator
    let iter = arr.iter().enumerate().filter(|(_, &x)| x != 0);

    // Print indices and values of non 0 elements in the array
    if reverse {
        print_iter(iter.rev());
    } else {
        print_iter(iter);
    }
}

fn print_iter<I: Display, T: Display>(iter: impl Iterator<Item = (I, T)>) {
    for (i, x) in iter {
        println!("index: {}, value: {}", i, x);
    }
}
Ответ принят как подходящий

Я нашел довольно компактное решение, используя ящик Either, вдохновленный этот ответ.

extern crate either;
use either::Either;

fn main() {
    // Array to observe
    let arr: [u8; 8] = [0, 2, 0, 0, 0, 1, 0, 5];
    // Reverse parameter
    let reverse: bool = true;

    // Pick the right iterator based on reverse
    let iter = match reverse {
        true => Either::Left(arr.iter().enumerate().filter(|(_, &x)| x!=0).rev()),
        false => Either::Right(arr.iter().enumerate().filter(|(_, &x)| x!=0))
    };

    // Print indices and values of non 0 elements in the array
    for (i, x) in iter {
        println!("index: {}, value: {}", i, x);
    }
}

>>> index: 7, value: 5
>>> index: 5, value: 1
>>> index: 1, value: 2

Это решение решает проблему, упомянутую hkBst (типы Iterator и его реверса разные), а также исходную ошибку компиляции «временное значение упало при заимствовании».

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