I have an
Iterator<Item = u32> but my function takes an
I: Iterator<Item = &u32>. Is there a way to "downgrade" my iterator to borrow the data instead of owning it?
iter.map(|i| &i) doesn't work:
70 | let borrowed = iter.map(move |c| &c);
| ^^ returns a reference to data owned by the current function
Not really, since an
Iterator can only "yield' values one by one and once the value is produced, it is, sort of, dis-associated with the iterator. So there is no real way to get a reference to the element.
On the other hand, if you can afford the storage, then you can
If you control the function taking
I: Iterator<Item = &u32>, I suggest
- Changing it to take
I: Iterator<Item = u32>
- Fixing everything that broke by adding a call to
As the latter step is a simple way to go the opposite direction.
It's good to take a step back here and thing about what borrowing means. When you're borrowing something, it's because it exists somewhere. If it doesn't exist anywhere, you can't borrow it.
Iterator<Item = u32> promises to give you
u32s when you ask for them. But they don't exist anywhere else -- it might be a
Range<u32>, for example, which doesn't have a bunch of owned things sitting around in memory somewhere, it just creates them when needed.
So you fundamentally can't just write a stateless lazy adapter that turns owned values into borrowed ones. You'd have to store them somewhere from which you can borrow them -- such as collecting them into a
Vec<u32>, then getting the
.iter() that gives out borrows of those items.
Thus as @quinedot said, the best solution here is to update your function to take owned items from the iterator. For trivial
Copy types like
u32, it's easier (and probably better performance, too!) to not bother with immutable borrows.