rust - Iterator filter() 双重引用借用错误

标签 rust

我正在尝试使用一些迭代器魔法编写一些 Rust 代码,但我遇到了双重引用和 Rust 文档的问题:

#[derive(PartialEq,Eq)]
pub enum Token {
    ECOND,
    SCOND
}

pub fn validate(pgm: &Vec<Token>) -> Result<(), ()> {
    let valid1 = pgm.iter()
                    .filter(|&&item|
                        item == Token::SCOND || item == Token::ECOND
                    )
                    .fold(0, |acc: i64, ref x| -> i64 {
                        if x == &&Token::SCOND {
                            return acc + 1;
                        } else {
                            return acc - 1;
                        }
                    });

    if valid1 != 0 {
        return Err(());
    }
    return Ok(());
}

它给我一个错误:

error: cannot move out of borrowed content [E0507]
                        .filter(|&&item|
                              ^~~~~
help: run `rustc --explain E0507` to see a detailed explanation
note: attempting to move value to here
                        .filter(|&&item|
                               ^~~~
help: to prevent the move, use `ref item` or `ref mut item` to capture value by reference

filter's doc 所述,通过双重引用,我可以用这些方式编写代码,并且它有效:

.filter(|&item|
    *item == Token::SCOND || *item == Token::ECOND
)

还有这样的:

.filter(|item|
    **item == Token::SCOND || **item == Token::ECOND
)

但是如何使用我的解决方案(也是文档解决方案)?我不明白我的错误在哪里。

最佳答案

你的Token之间的主要区别和文档的 i32那是i32吗是Copy .

默认情况下,Rust 类型是仿射类型:它们最多只能使用(按值传输)一次。 Copy类型是规则的异常(exception),它们可以使用任意次,因为使用它们不会转移所有权,它会默默地产生一个 Clone相反。

因此,除非您的 Token打字Copy (这也需要 Clone ),您不能使用 filter 文档中提供的第三种形式.

您可以简单地使用:

#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Token { .... }

让它成为Copy ,或者不使用第三种形式。我会建议后者,除非你愿意向你的客户保证它将保持不变 Copy .

关于rust - Iterator filter() 双重引用借用错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38219929/

相关文章:

python - Maturin 项目背后有 Python 绑定(bind)功能

rust - 在 T 和 UnsafeCell<T> 之间转换是否安全且已定义行为?

rust - 了解循环中的不可变借用

rust - 当目标架构是 WASM 时默认启用 Cargo 功能?

rust - 自定义迭代器中可变引用的生命周期参数问题

rust - 默认情况下,Rust 闭包是堆栈分配还是堆分配?

rust - 如何在 Rust 中过滤索引上的向量

regex - 如何在不环顾的情况下匹配单括号而不是双括号之间的单词?

casting - 将 Vec<u32> 就地转换为 Vec<u8> 且开销最小

rust - Cloudflare Workers 中的内存不足 WebAssembly 实例化