【问题标题】:How can I return an iterator over a slice?如何在切片上返回迭代器?
【发布时间】:2015-06-16 16:54:17
【问题描述】:
fn main() {
    let vec: Vec<_> = (0..5).map(|n| n.to_string()).collect();

    for item in get_iterator(&vec) {
        println!("{}", item);
    }
}

fn get_iterator(s: &[String]) -> Box<Iterator<Item=String>> {
    Box::new(s.iter())
}

【问题讨论】:

    标签: iterator closures rust


    【解决方案1】:
    fn get_iterator<'a>(s: &'a [String]) -> Box<Iterator<Item=&'a String> + 'a> {
        Box::new(s.iter())
    }
    

    这里的诀窍是我们从一个项目切片开始,该切片的生命周期为'aslice::iter 返回一个与切片具有相同生命周期的 slice::IterIterator 的实现同样返回具有该生命周期的引用。我们需要将所有生命联系在一起。

    这解释了参数和Item=&amp;'a 部分中的'a。那么+ 'a 是什么意思?有一个complete answeranother with more detail。简短的版本是,一个具有内部引用的对象可以实现一个特征,所以我们在谈论一个特征时需要考虑这些生命周期。默认情况下,该生命周期为 'static,因为已确定这是通常的情况。

    Box 不是严格要求的,但是当您不想处理可能作为实现基础的复杂类型(或者只是不想公开实现)时,您会看到这是正常的事情.在这种情况下,函数可以

    fn get_iterator<'a>(s: &'a [String]) -> std::slice::Iter<'a, String> {
        s.iter()
    }
    

    但如果你添加.skip(1),类型将是:

    std::iter::Skip<std::slice::Iter<'a, String>>
    

    如果您涉及闭包,则目前无法指定类型,因为闭包是唯一的、匿名的、自动生成的类型!这些情况需要Box

    【讨论】:

    • 对我来说,盒子毫无意义,我错过了什么吗?
    猜你喜欢
    • 2023-01-08
    • 2019-07-23
    • 2015-06-08
    • 1970-01-01
    • 2015-02-04
    • 2016-04-16
    • 2011-01-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多