-
Notifications
You must be signed in to change notification settings - Fork 13.5k
hashmap: Remove .consume() methods #7833
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Why not have the same semantics as today where it simply empties the hashmap, but the hashmap is still usable after consumption? |
We could, but it would not be consistent with vec's consume_iter. Also both alternatives have uses. By-value consume iter is useful if you want to pass the iterator on as an owned value. |
This is always going to be a by-value iterator. There really aren't that many consume iterators and the one I recently added to Plus, sometimes it's kind of nice to keep the same hashmap around for multiple iterations of some code. Between iterations you consume all key/value pairs, but you don't have to re-allocate the entire map (and re-seed it from the task-local RNG). I'd still vote for taking As a side note, I named the method for map.consume |(key, value)| {
// ...
} Having the |
I think all consume iterators should be consistent. They are not only for direct use but also for use with the IteratorUtil methods. |
What does it mean to be consistent and to be used with Consistency among implementations is an entirely different matter. So far maps are on the trend to take |
@alexcrichton, fwiw, there's a pile of |
@huonw, I agree, although if this is removing the |
the IteratorUtil thing is just that, for direct use with for, by-value or by-mut-ref doesn't matter, but when you encapsulate the hashmap inside an IteratorUtil combinator, it does make a difference for how that value can be passed around. Since the awkward dance with util::replace only appears where the code is using @mut HashMap, I think this is fine as it is. |
@blake2-ppc, I think there's a disconnect between what you and I are thinking, so here's what I thought the consume method could be like fn consume(&mut self) -> SomeIterator<(K, V)> {
let arr = util::replace(&mut self.slots, ~[]);
arr.consume_iter().filter_map(|x| match x { Some(slot) => Some((slot.key, slot.value)), None => None })
} There's no constraints on what you're iterating over or anything like that. The only difference is that you can still use the hashmap after you consume it. The values owned by the hashmap are still moved into the iterator that you return. |
Nice, didn't look at your Smallintmap. That behavior is the best of both worlds, only problem is the extra allocation and copy of ~[], can the compiler optimize that away (when applicable) if the method is inline? |
Hmm... That is a good point. I doubt that the compiler would optimize away the allocation because that's a very complicated function to determine is useless. That actually puts me more in favor of what it is today actually because "consumption" essentially means transferring ownership and it shouldn't really involve reallocations. |
If you rename |
Updated all users of HashMap, HashSet old .consume() to use .consume() with a for loop. Since .consume() takes the map or set by value, it needs awkward extra code to in librusti's use of @mut HashMap, where the map value can not be directly moved out.
Renamed to .consume(), no other changes. |
@alexcrichton would you mind if consume() gets renamed to move_iter() ? |
Add reference to another doc with explanation Add reference to another doc that explains which repository should be passed in this command since this is not covered in the command help itself. changelog: none
Updated all users of HashMap, HashSet ::consume() to use
.consume_iter().
Since .consume_iter() takes the map or set by value, it needs awkward
extra code to in librusti's use of @mut HashMap, where the map value can
not be directly moved out.
Addresses issue #7719