Write a trait that returns an iterator
Notice in particular with this example that:
trait HasValsIterator<'a, T: 'a> {
fn val_iterator(&'a self) -> T where T: Iterator<Item = Val>;
}
Has a lifetime 'a
on the trait although the trait itself has no references; this is typically not required, but means that we can, in this case, implement it for a T which has a lifetime on it:
impl<'a> HasValsIterator<'a, ValsFromT<'a, Foo>> for Foo {
fn val_iterator(&'a self) -> ValsFromT<'a, Foo> {
...
Without the explicit lifetime on the trait, we would hit an error that looks like:
<anon>:22:3: 27:4 error: method `val_iterator` has an incompatible type for trait:
expected bound lifetime parameter ,
found concrete lifetime [E0053]
<anon>:22 fn val_iterator(&'a self) -> ValsFromT<'a, Foo> {
<anon>:23 return ValsFromT {
<anon>:24 offset: 0usize,
<anon>:25 parent: self
<anon>:26 };
<anon>:27 }
<anon>:22:3: 27:4 help: see the detailed explanation for E0053
...which is exactly what it's saying; the trait &self
reference is not the 'a
that the function expects.
struct ValsFromT<'a, T: 'a> {
parent: &'a T,
offset: usize,
}
struct Val;
trait HasValsIterator<'a, T: 'a> {
fn val_iterator(&'a self) -> T where T: Iterator<Item = Val>;
}
struct Foo;
impl<'a> Iterator for ValsFromT<'a, Foo> {
type Item = Val;
fn next(&mut self) -> Option<Val> {
return None;
}
}
impl<'a> HasValsIterator<'a, ValsFromT<'a, Foo>> for Foo {
fn val_iterator(&'a self) -> ValsFromT<'a, Foo> {
return ValsFromT {
offset: 0usize,
parent: self
};
}
}
fn takes_vals<'a, T, U: 'a>(instance: T) where T: HasValsIterator<'a, U> {
// ...
}
#[test]
fn test_foo() {
let x = Foo;
takes_vals(x);
}