'temporary value dropped while borrowed' 根据条件创建迭代器时

'temporary value dropped while borrowed' when creating Iterator based in condition

我正在尝试在 Rust 中构建一个 Iterator,returns 数组中非空元素的值和索引。根据 bool 参数,此 Iterator 应该是可逆的。

我设法在没有 reverse 条件的情况下构建了 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);
    }
}

我曾尝试克隆数组,或按照编译器的建议使用 let 关键字声明 Iterator,但其中的 none 似乎有效。有什么想法吗?

您的代码中的问题是您引用了一个临时变量。

在尝试修复它时,您将不得不解决其他几个与迭代器有关的问题,例如在一个迭代器上使用 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提到的问题(types of an Iterator and its reverse being different),以及原来的'temporary value dropped while borrowed'编译错误。