为什么iter()需要&对于lambda函数,而范围不在此示例中

时间:2014-05-03 05:41:04

标签: rust

我在理解这个例子中的差异时遇到了一些麻烦:

我认为range(..)iter()都是std::iter::Iterator 那么为什么我可以将第一个示例中的|x|传递给mapfilter,但是必须在第二个示例中将其作为|&x|传递?

use std::iter::AdditiveIterator;

fn main() {
    let range1 = range(1,9);
    let range2 = [1,2,3,4,5,6,7,8,9];

    //indented for easier visualization
    let sum1 = range1       .map(| x| x * x).filter(| x| x % 2 == 0).sum();
    let sum2 = range2.iter().map(|&x| x * x).filter(|&x| x % 2 == 0).sum();

    println!("{}", sum1);
    println!("{}", sum2);
}

1 个答案:

答案 0 :(得分:5)

在不知道Iterator类型参数的情况下,只知道它们都是Iterator并不会告诉您有关它们迭代的内容,这是重要的区别。对于此代码:

  • range1Iterator<int>
  • range2.iter()Iterator<&int>

也就是说,slice iterator返回直接指向切片的引用(它必须执行此操作,或者对于一般T,它会尝试从借用的切片中窃取所有权{{1} }:非法),而&[T]只返回计数器的值,因为它在内部构造它,并且可以自由地将其移出(“转移所有权”)。

因此,要从切片迭代器中获取range,您需要以某种方式取消引用该引用,例如通过int进行模式匹配,或者编写|&x| ...