Iterators are lazy, therefore they must borrow their input:
- this requires that their input lives longer than they do
- this requires, for safety reason, that the borrowing relationship be exposed at function boundaries
The former point requires that the buf be passed as a reference and not a value.
The latter point prevents you from returning a generic Iterator<Item=u32> (even boxed) because it hides the borrowing relationship between the returned iterator and the passed in buffer. So instead you must be explicit:
use std::io;
fn read_and_iter_u32_line<'a>(buf: &'a mut String)
-> std::iter::Map<std::str::SplitWhitespace<'a>, fn(&'a str) -> u32>
{
fn convert(s: &str) -> u32 { s.parse().unwrap() }
buf.truncate(0);
io::stdin().read_line(buf).unwrap();
buf.split_whitespace().map(convert)
}
fn main() {
let mut buf = "".to_string();
for i in read_and_iter_u32_line(&mut buf) {
println!("{}", i);
}
}
Note: actually, the lifetime annotation can be elided, but I have exposed it here to highlight why the generic iterator is not possible.