我正在尝试使用一些迭代器魔法编写一些 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/