Unconstrained lifetime parameter

I totally loss with lifetime declaration.
My humble code:

struct Data{
	a: i32,
	b: i32,
	c: i32
}

impl Data {
    fn new(a:i32, b:i32, c:i32) -> Self{
        Data{a,b,c}
    }
}


struct DataIter<'a> {
	data: &'a Data,
	pos: i32
}

impl Iterator for DataIter<'_> {
    type Item=i32;
    fn next(&mut self) -> Option<Self::Item>{
        match self.pos {
            0 => { self.pos+=1; Some(self.data.a)}
            1 => { self.pos+=1; Some(self.data.b)}
            2 => { self.pos+=1; Some(self.data.c)}
            _ => None
        }
    }
}


impl<'a> IntoIterator for Data{
    type Item=i32;
    type IntoIter = DataIter<'a>;
    fn into_iter<'a>(&'a self) -> Self::IntoIter {
        DataIter{data:&self, pos: 0}
    }
}

fn main() {
	let d = Data::new(1, 2, 3);
	for a in d{
		println!("{}", a);
    }
}

It does not compile: unconstrained lifetime parameter
If I remove it from impl and IntoIter, it complains that DataIter need a lifetime parameter.
If I declare it in fn into_iter, it complains that this is double declaration.
If I remove it from impl and left in into_iter, it complains that a is not defined for IntoIter.

I understand all errors except for the first one: why it's unconstrained, if it's in arguments for into_iter and in type IntoIter?

Oh, it was simple.

impl<'a> IntoIterator for &'a Data{

It just says we implement IntoIterator not for Data, but for reference to Data.

Why dont you just get rid of the lifetime parameter?

struct DataIter {
	data: Data,
	pos: i32
}

If I rid of lifetime parameter (actually, converts data from reference to Data into Data), my iterator becomes consuming. I already done this and moved to non-consuming iterators.

You data can be Copy so there isn't really a difference between consuming and by reference.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.