有趣的by_ref()
是它返回一个对自身的可变引用:
pub trait IteratorExt: Iterator + Sized {
fn by_ref(&mut self) -> &mut Self { self }
}
它之所以有效,是因为该Iterator
特征是为指向 Iterator类型的可变指针实现的。聪明的!
impl<'a, I> Iterator for &'a mut I where I: Iterator, I: ?Sized { ... }
标准函数之所以有效,是因为它使用了自动解析为take_while
的 trait 。Iterator
&mut Peekable<T>
但是你的代码不起作用,因为Peekable
它是一个结构,而不是一个特征,所以你CautiousTakeWhileable
必须指定类型,并且你试图获得它的所有权,但你不能,因为你有一个可变指针。
解决方案,不要采取Peekable<T>
but &mut Peekable<T>
。您还需要指定生命周期:
impl <'a, T: Iterator, P> Iterator for CautiousTakeWhile<&'a mut Peekable<T>, P>
where P: FnMut(&T::Item) -> bool {
//...
}
impl <'a, T: Iterator> CautiousTakeWhileable for &'a mut Peekable<T> {
fn cautious_take_while<P>(self, f: P) -> CautiousTakeWhile<&'a mut Peekable<T>, P>
where P: FnMut(&T::Item) -> bool {
CautiousTakeWhile{inner: self, condition: f,}
}
}
这个解决方案的一个奇怪的副作用是 nowby_ref
不需要,因为cautious_take_while()
它需要一个可变引用,所以它不会窃取所有权。by_ref()
调用是必需的,因为take_while()
它可以采用Peekable<T>
or &mut Peekable<T>
,并且默认为第一个。通过by_ref()
调用,它将解析为第二个。
现在我终于明白了,我认为更改 的定义struct CautiousTakeWhile
以将可窥视位包含到结构本身中可能是一个好主意。如果我是对的,困难在于必须手动指定生命周期。就像是:
struct CautiousTakeWhile<'a, T: Iterator + 'a, P>
where T::Item : 'a {
inner: &'a mut Peekable<T>,
condition: P,
}
trait CautiousTakeWhileable<'a, T>: Iterator {
fn cautious_take_while<P>(self, P) -> CautiousTakeWhile<'a, T, P> where
P: FnMut(&Self::Item) -> bool;
}
其余的或多或少是直截了当的。