为Iterator :: find提供闭包时的值和引用

Hem*_*mar 1 rust

我在学习Rust方面还有很长的路要走,但我发现使用值和引用的方式不一致.这可能源于我对语言的无知.

例如,这有效:

let x = (1..100).find(|a| a % 2 == 0);
Run Code Online (Sandbox Code Playgroud)

let x = (1..100).find(|a| a > 50);事实并非如此.我不确定 - 为什么呢?

使用let x = (1..100).find(|&a| a > 50);修复错误,但后来我认为使用&a就像是要求从范围引用元素,因此后续应该工作,但它不会:

let x = (1..100).find(|&a| *a > 50);
Run Code Online (Sandbox Code Playgroud)

再也不知道为什么!

Vla*_*eev 6

但后来我认为使用&a就像是要求从范围中引用元素

是你推理的错误部分.&在模式中使用恰恰相反 - 它隐式地取消引用匹配的值:

let &a = &10;
// a is 10, not &10 or &&10
Run Code Online (Sandbox Code Playgroud)

正如您可能已经知道的那样,find()接受一个满足的闭包FnMut(&T) -> bool,也就是说,此闭包接受对迭代器的每个元素的引用,因此如果您编写(1..100).find(|a| ...),a将是类型&i32.

let x = (1..100).find(|a| a % 2 == 0)因为算术运算符被重载以处理引用,所以你可以应用于%引用,它仍然可以编译.

比较运营商不超载处理引用,所以你需要得到一个i32&i32.这可以通过两种方式完成,首先,就像你已经做过的那样:

let x = (1..100).find(|&a| a > 50)
Run Code Online (Sandbox Code Playgroud)

这里我们使用&模式隐式取消引用函数参数.它相当于这个:

let x = (1..100).find(|a| { let a = *a; a > 50 })
Run Code Online (Sandbox Code Playgroud)

另一种方法是明确地取消引用该参数:

let x = (1..100).find(|a| *a > 50)
Run Code Online (Sandbox Code Playgroud)