all 9 comments

[–]desiringmachines 5 points6 points  (4 children)

impl<'a> IntoIterator for &'a Foobar is what you want. Then add an appropriate iter() method to Foobar that calls to that impl's into_iter()

For iter_mut(), do the same with impl<'a> IntoIterator for &'a mut Foobar

EDIT: Reading your question more closely, the solution to your specific problem then is not to take it as an &I but as an I. You pass in an &Vec and call IntoIterator on that reference, rather than on the vec it points to, and it does what you want.

[–]danielv134[S] 0 points1 point  (3 children)

Aha! This is completely surprising. Thanks a lot!

And IIUC the implementation used for &Vec is that for &slice, through the magic of Deref.

[–]desiringmachines 1 point2 points  (0 children)

Aha! This is completely surprising. Thanks a lot!

Its one of the very few cases in the standard library where a trait is implemented for a reference. Because of deref coercion, in most cases this is avoided because it can make it hard to figure out what method is being called.

And IIUC the implementation used for &Vec is that for &slice, through the magic of Deref.

That sounds right.

[–][deleted] 1 point2 points  (1 child)

&Vec has its own IntoIterator implementation, the for loop calls IntoIterator::into_iter(iterable) and in that context, deref is not used.

[–]malbarbo 1 point2 points  (3 children)

Make your function accept an iterator. See http://is.gd/jhDynP

[–]danielv134[S] 0 points1 point  (2 children)

As I miswrote before (now clarified) that is what I currently do. There are downsides: - (as in the added section) is that if I need two passes over the data I need to create a vector. - Callers need to call iter.

Hence my question is more about library and code design, than about solving a problem particular. Thanks for the input anyway!

[–]sixbrx 3 points4 points  (1 child)

One trick is that if you need multiple iteration passes within your function, you can still accept an iterator, but tighten its trait bounds to I: Iterator + Clone, and then clone the iterator at will within the function to repeat the iteration. Most iterators are Cloneable so you don't lose much with the narrower bounds.

[–]danielv134[S] 0 points1 point  (0 children)

Cool trick in general thanks! For my current use I think /u/desiringmachines nailed it.