Hello,
The code below returns an iterator object and works fine
use std::marker::PhantomData;
struct MyContainer<'a> {
records : Vec<String>,
phantom : PhantomData<&'a ()>,
}
struct MyElementPointer<'a> {
container : &'a MyContainer<'a>,
record : &'a String
}
impl <'a>MyContainer<'a> {
pub fn iter<'incoming>(&'incoming self) -> Box<dyn Iterator<Item=MyElementPointer<'incoming>> + 'incoming> {
Box::new(self.records.iter().map(move |record| MyElementPointer{container : self, record : record}))
}
}
fn main() {
let my_container = MyContainer{phantom : PhantomData, records : vec!["one".to_string(), "two".to_string(), "three".to_string()]};
for pointer in my_container.iter() {
println!("{} of {}", pointer.record, pointer.container.records.len());
}
}
But when I make the container into a dyn trait object, it fails.
use std::marker::PhantomData;
struct MyContainer<'a> {
records : Vec<String>,
phantom : PhantomData<&'a ()>,
}
struct MyElementPointer<'a> {
container : &'a dyn ContainerTrait<'a>,
record : &'a String
}
impl <'a>ContainerTrait<'a> for MyContainer<'a> {
fn iter<'incoming>(&'incoming self) -> Box<dyn Iterator<Item=MyElementPointer<'incoming>> + 'incoming> {
Box::new(self.records.iter().map(move |record| MyElementPointer{container : self, record : record}))
}
}
trait ContainerTrait<'a> {
fn iter<'incoming>(&'incoming self) -> Box<dyn Iterator<Item=MyElementPointer<'incoming>> + 'incoming>;
}
fn main() {
let my_container = MyContainer{phantom : PhantomData, records : vec!["one".to_string(), "two".to_string(), "three".to_string()]};
for pointer in my_container.iter() {
println!("{} of {}", pointer.record, pointer.container.records.len());
}
}
There is no problem if the container doesn't have a lifetime bound (hence the PhantomData). Somehow it's the interaction of the lifetime bound of the trait object with the variable capture of the closure.
Has anyone found a work-around for this?
Thank you.