在Rust Book中有一个调用filter()迭代器的例子:
for i in (1..100).filter(|&x| x % 2 == 0) {
println!("{}", i);
}
Run Code Online (Sandbox Code Playgroud)
下面有一个解释,但我无法理解它:
这将打印一到一百之间的所有偶数.(请注意,因为过滤器不使用正在迭代的元素,所以它会传递对每个元素的引用,因此过滤谓词使用&x模式来提取整数本身.)
然而,这不起作用:
for i in (1..100).filter(|&x| *x % 2 == 0) {
println!("i={}", i);
}
Run Code Online (Sandbox Code Playgroud)
为什么闭包的参数是参考|&x|,而不是|x|?使用|&x|和有|x|什么区别?
我知道使用引用|&x|更有效,但我很困惑的事实是我不必x通过使用取消引用指针*x.
当用作模式匹配(并且闭包和函数参数也是模式匹配)时,& 绑定到引用,使变量成为解除引用的值.
fn main() {
let an_int: u8 = 42;
// Note that the `&` is on the right side of the `:`
let ref_to_int: &u8 = &an_int;
// Note that the `&` is on the left side of the `:`
let &another_int = ref_to_int;
let () = another_int;
}
Run Code Online (Sandbox Code Playgroud)
有错误:
error: mismatched types:
expected `u8`,
found `()`
Run Code Online (Sandbox Code Playgroud)
如果您查看案例的错误消息,则表示您无法取消引用它,因为它不是引用:
error: type `_` cannot be dereferenced
Run Code Online (Sandbox Code Playgroud)
我没有必要使用*x取消引用x指针.
那是因为你在模式匹配中隐式取消引用它.
我理解使用引用|&x | 效率更高
如果这是真的,那么除了参考之外没有理由使用任何东西!也就是说,引用需要额外的间接来获取真实数据.有一些可衡量的截止点,按值传递项目比传递对它们的引用更有效.
如果是这样,为什么使用
|x|不抛出错误?根据我对C的经验,我希望在这里收到一个指针.
你以参考的形式做到了.x是(在这个例子中)的参考i32.但是,%运算符由特征提供,该特征Rem是针对所有参考/值对实现的:
impl Rem<i32> for i32
impl<'a> Rem<i32> for &'a i32
impl<'a> Rem<&'a i32> for i32
impl<'a, 'b> Rem<&'a i32> for &'b i32
Run Code Online (Sandbox Code Playgroud)
这允许您不需要显式取消引用它.
或者Rust会在这里隐式地
x在堆栈上分配原始值的副本吗?
它强调并没有做到这一点.实际上,这样做是不安全的,除非实现了迭代的项目Copy(或者可能Clone,在这种情况下,它也可能是昂贵的).这就是引用用作闭包参数的原因.