【问题标题】:How to create an empty iterator for a certain collection type (list/set/map) in Rust?如何在 Rust 中为某个集合类型(list/set/map)创建一个空迭代器?
【发布时间】:2015-08-29 08:59:15
【问题描述】:

我想编写一个返回集合迭代器的方法(例如 LinkedList)。但在某些情况下,没有合适的集合来返回 的迭代器。在这种情况下,我想返回一个“空”迭代器 迭代没有元素。但我找不到任何相关的功能 在documentation 中构造一个linked_list::Iter。

考虑以下示例:

use std::collections::HashMap;
use std::collections::LinkedList;
use std::collections::linked_list;

pub struct Graph {
    nodes: HashMap<usize, LinkedList<usize>>,
}

impl Graph {
    pub fn adjacent_nodes(&self, node: usize) -> linked_list::Iter<usize> {
        match self.nodes.get(&node) {
            Some(x) => x.iter(),
            _ => linked_list::Iter::<usize>::new()
        }
    }
}

我想从adjacent_nodes 返回相邻节点的迭代器 方法。但是当询问不存在节点的邻居时,该方法应该 显然,返回一个迭代器。但我怎么能创造它?编码 我给的实际上并没有编译:

src/graph.rs:13:18: 13:49 error: no associated item named `new` found for type
        `collections::linked_list::Iter<'_, usize>` in the current scope
src/graph.rs:13             _ => linked_list::Iter::<usize>::new()
                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

我想,我可以用boxed::Box 解决这个问题,但这显然是一个 由于我试图避免不必要的堆分配,因此不是最佳解决方案。

所以,我的问题是:在 Rust 中是否有可能创建一个无上的迭代器 具体类型?

【问题讨论】:

    标签: iterator rust


    【解决方案1】:

    你不能这样做,而不是通过引用迭代器,因为它们总是绑定到一个具体的集合实例。

    您可以做的是将盒装迭代器作为特征对象返回:

    pub fn adjacent_nodes<'a>(&'a self, node: usize) -> Box<Iterator<Item=usize>+'a> {
        match self.nodes.get(&node) {
            Some(x) => Box::new(x.iter()),
            _ => Box::new(::std::iter::empty())
        }
    }
    

    std::iter::empty() 返回一个空的迭代器,但是它的类型当然和集合迭代器的类型不同,所以你必须使用一个 trait 对象。我还必须添加一个生命周期参数,因为iter() 返回的迭代器与self.nodes 绑定,您需要向编译器解释它。

    【讨论】:

    • 感谢您的回答。但我不太明白为什么必须将空迭代器绑定到具体的集合实例。在我看来,它就像标准库中的一个缺陷。像这样不必要的堆分配肯定不是零成本抽象。
    • 如果你需要那种特殊的类型。切片迭代器是一个例外:[].iter() 和 [].iter_mut() 都应该没问题。
    • 我会使用这两种情况的枚举而不是使用盒装迭代器。
    • @bluss,[] 不是一个空数组吗?它具有相同的所有权语义,并且在函数结束后将被销毁,因此您不能从中返回迭代器。另外,有两种情况的枚举需要手动实现Iterator,但是是的,这是一个可行的解决方案。
    • @Nikolai,空迭代器和非空迭代器没有区别。重要的是迭代器类型。 Iterator 是一个特征,并且有一些类型实现了这个特征。每个集合都有自己的迭代器类型,因为数据结构不同,迭代器必须了解集合实现。因此,不同集合的迭代器是不兼容的。当迭代器产生引用时会出现更多问题,因为它们通过类型中的生命周期参数绑定到集合。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-17
    • 1970-01-01
    • 2019-05-30
    • 2015-04-28
    • 1970-01-01
    • 2019-12-13
    • 1970-01-01
    相关资源
    最近更新 更多