在Rust Book中有一个在迭代器上调用filter()
的例子:
for i in (1..100).filter(|&x| x % 2 == 0) {
println!("{}", i);
}
下面有一个解释,但我无法理解它:
这将打印一到一百之间的所有偶数。 (注意,因为过滤器不会消耗正在迭代的元素,所以它会传递给每个元素的引用,因此过滤谓词使用&amp; x模式来提取整数本身。)< /强>
然而,这不起作用:
for i in (1..100).filter(|&x| *x % 2 == 0) {
println!("i={}", i);
}
为什么闭包的参数是引用|&x|
,而不是|x|
?使用|&x|
和|x|
之间的区别是什么?
我知道使用引用|&x|
会更有效率,但我对我不必使用{{1 }}
答案 0 :(得分:8)
当用作模式匹配(并且闭包和函数参数也是模式匹配)时,&
绑定到引用,使变量解除引用价值。
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;
}
有错误:
error: mismatched types:
expected `u8`,
found `()`
如果您查看针对您的案例的错误消息,则表示您无法取消引用它,因为不是参考:
error: type `_` cannot be dereferenced
我没有必要使用* x来取消引用x指针。
那是因为你在模式匹配中隐式取消引用它。
我理解使用引用|&amp; 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
这使您无需明确取消引用它。
或者,Rust会在堆栈中隐式分配原始
x
的值副本吗?
强调不这样做。实际上,这样做是不安全的,除非迭代项目实现Copy
(或可能Clone
,在这种情况下它也可能很昂贵)。这就是引用被用作闭包参数的原因。