我正在尝试为实现特征的结构体实现一种默认迭代器。我的特性称为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
以解决此问题。我的演示代码包括发生错误的注释,请点击此处:
https://play.rust-lang.org/?gist=dc128a133ffb5d7471d47d130520936d&version=stable
如何为自定义特征实现这样的“默认迭代器”?
答案 0 :(得分:3)
您可以为特征对象引用实现IntoIterator
。
impl<'a> IntoIterator for &'a DataRow<'a> {
type Item = &'a DataCell<'a>;
type IntoIter = DataRowIterator<'a>;
fn into_iter(self) -> DataRowIterator<'a> {
return DataRowIterator::new(self);
}
}
应修改 DataRowIterator
以保留特征对象引用&DataRow
而不是&T
,并使用DataRow
特征可用的方法。