简体   繁体   English

如何为特征实现“默认迭代器”?

[英]How can I implement a “default iterator” for a trait?

I am trying to implement a default iterator for structs implementing a trait. 我正在尝试为实现特征的结构实现默认迭代器。 My trait is called DataRow , represents a row of table cells, and looks like this: 我的特性称为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;
}

The default iterator I want to provide should use those two methods to iterate over the row and return cell references. 我想提供的默认迭代器应该使用这两个方法迭代行并返回单元格引用。 In Java this would boil down to an abstract class DataRow that implements Iterable . 在Java中,这将归结为实现Iterable的抽象类DataRow In Rust I tried first with IntoIterator : 在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);
    }
}

This does not work as anyone could implement their own iterator for their own implementation of the DataRow trait. 这不起作用,因为任何人都可以为自己的DataRow特性实现实现自己的迭代器。

My second try was adding an iter method to the trait which creates the iterator and returns it: 我的第二次尝试是在trait中添加一个iter方法,它创建迭代器并返回它:

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

This does not work either, because the size of Self is not known at compile time. 这也不起作用,因为在编译时不知道Self的大小。 Since DataRow can contain an arbitrary number of cells, I also cannot mark it as Sized to get around that. 由于DataRow可以包含任意数量的单元格,因此我也无法将其标记为Sized以便绕过它。

My demo code including notes on the occurring errors 我的演示代码包括发生错误的注释

How would someone implement such a "default iterator" for a custom trait? 如何为自定义特征实现这样的“默认迭代器”?

You can implement IntoIterator for a trait object reference. 您可以为特征对象引用实现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 should be modified to keep the trait object reference &DataRow instead of &T and use the methods available for the DataRow trait. 应修改DataRowIterator以保留特征对象引用&DataRow而不是&T并使用DataRow特征可用的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM