简体   繁体   中英

How to map to references if it's not an Iterator<Item=&T>?

I have a function that receives Iterator<Item=AsRef> and I wanted to get an array of substrings form this iterator. The issue is that when mapping, .map() gets ownership of AsRef and I can't return as_ref() . How can I turn this iterator into an iterator of references like with Vec::iter? Sample code:

fn a(lines: impl Iterator<Item=impl AsRef<str>>) {
    println!("{:?}", lines.map(|s| s.as_ref()).collect::<Vec<&str>>());
}

a(vec!["one".to_string(), "two".to_string()].iter());

Its a bit problematic to do with just an iterator. As signature describes, iterator can very match own the Item (s) and transfer the ownership to you inside the closure. Consider taking &impl AsRef<str> instead. This should not be a problem to provide at the caller site.

EDIT

It is actually tricky on the caller side too. Im using a ReadBuf that returns an Iterator<Item=String>. How would you turn this iterator into an Iterator<Item=&String>?

BufRead will read lines as you demand them and it is designed to wait on the input. To use it properly and with memory efficiency, I'd recommend processing each line in a loop and discarding it before reading the next.

That's the solution I found but it seems very costly having to allocate an entire Vec just to get the references of items I already own in the iterator.

Iterator does not in fact own all the strings at the same time. Instead it reads them in batches (or it should) and it does not store them internally for you to reference them (or at least it should not).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM