我该如何为一个特质实现“默认迭代器”?

6

我正在尝试为实现了一个trait的结构体实现默认迭代器。我的trait叫做DataRow,表示一行表格单元格,并且看起来像这样:

pub trait DataRow<'a> {
    // Gets a cell by index
    fn getCell(&self, i: usize) -> &DataCell<'a>;

    // Gets the number of cells in the row
    fn getNumCells(&self) -> usize;
}

我想提供的默认迭代器应该使用这两种方法来遍历行并返回单元格引用。 在Java中,这将归结为实现Iterable的抽象类DataRow。而在Rust中,我首先尝试了IntoIterator

impl<'a, T> IntoIterator for &'a T
where
    T: DataRow<'a>,
{
    type Item = &'a DataCell<'a>;
    type IntoIter = DataRowIterator<'a, T>;

    fn into_iter(self) -> DataRowIterator<'a, T> {
        return DataRowIterator::new(self);
    }
}

这种方式行不通,因为任何人都可以为他们自己实现的DataRow特质实现自己的迭代器。

我的第二次尝试是在特质中添加一个iter方法来创建并返回迭代器:

fn iter(&self) -> DataRowIterator<'a, Self> {
    return DataRowIterator::new(self);
}

这也不起作用,因为在编译时无法确定Self的大小。由于DataRow可以包含任意数量的单元格,因此我也无法将其标记为Sized以解决这个问题。 我的演示代码包括出现错误的注释 有什么方法可以为自定义特性实现这样的“默认迭代器”呢?
1个回答

4
您可以为特质对象引用实现IntoIterator
impl<'a> IntoIterator for &'a DataRow<'a> {
    type Item = &'a DataCell<'a>;
    type IntoIter = DataRowIterator<'a>;

    fn into_iter(self) -> DataRowIterator<'a> {
        DataRowIterator::new(self)
    }
}

DataRowIterator 应该修改为保留特质对象引用 &DataRow 而不是 &T,并使用DataRow 特质可用的方法。


{btsdaf} - AlexanderF
1
需要进行某种类型的转换,因为正如你所说,“任何人都可以为自己实现的DataRow特性实现自己的迭代器”。你可以创建一个辅助函数fn def_iter<T: DataRow>(p: &T) -> &DataRow { p },然后代码将变为for cell in def_iter(&row)。顺便说一下,你不需要使用ref,cell已经是一个引用了。 - red75prime
That makes sense. Thank you! - AlexanderF

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接