具有返回迭代器的函数的trait

时间:2015-07-08 08:53:18

标签: iterator rust traits

我试图用返回迭代器的函数构建一个特征。

我的简单示例如下:

pub trait TraitA {
    fn things(&self) -> Iterator<Item=&u8>;
}

fn foo<A: TraitA>(a: &A) {
    for x in a.things() { }
}

这不起作用,因为在编译时不知道迭代器大小类型。

2 个答案:

答案 0 :(得分:7)

Rust的libstd有一个实现,即特征IntoIterator

/// Conversion into an `Iterator`
pub trait IntoIterator {
    /// The type of the elements being iterated
    type Item;

    /// A container for iterating over elements of type `Item`
    type IntoIter: Iterator<Item=Self::Item>;

    /// Consumes `Self` and returns an iterator over it
    fn into_iter(self) -> Self::IntoIter;
}

该特征具有这种特殊的按值(self)公式,完全能够表达“迭代器”和“借用迭代器”语义。

由HashMap的IntoIterator实现演示。 (他们使用hashmap的迭代器结构IterIntoIter。)这里有趣的是,为&HashMap<K, V, S>类型实现了特征来表达“借用迭代器”。

impl<'a, K, V, S> IntoIterator for &'a HashMap<K, V, S>
    where K: Eq + Hash, S: HashState
{
    type Item = (&'a K, &'a V);
    type IntoIter = Iter<'a, K, V>;

    fn into_iter(self) -> Iter<'a, K, V> {
        self.iter()
    }
}

impl<K, V, S> IntoIterator for HashMap<K, V, S>
    where K: Eq + Hash, S: HashState
{
    type Item = (K, V);
    type IntoIter = IntoIter<K, V>;

    /// Creates a consuming iterator, that is, one that moves each key-value
    /// pair out of the map in arbitrary order. The map cannot be used after
    /// calling this.
    fn into_iter(self) -> IntoIter<K, V> {
        /* ... */
    }
}

答案 1 :(得分:2)

基于另一个question,我认为最好的方法是将Iterator定义为特征类型,如下所示:

pub trait TraitA<'a> {
    type I1: Iterator<Item=u8>;
    type I2: Iterator<Item=&'a u8>;

    fn iter_i1(&self) -> Self::I1;
    fn iter_i2(&self) -> Self::I2;
}

fn foo<'a, A: TraitA<'a>>(a: &A) {
    for x in a.iter_i1() { }
    for x in a.iter_i2() { }
}