rust
rust copied to clipboard
Tracking Issue for `Option::get_or_insert_default`
Feature gate: #![feature(option_get_or_insert_default)]
This is a tracking issue for adding Option::get_or_insert_default
.
Basically, it is a shorthand for option.get_or_insert_with(Default::default)
. It differs with unwrap_or_default
since it does not consume the Option
. This is useful, for example, when you have an Option
as a struct field or inside a data structure like Vec<Option<T>>
.
Public API
impl<T> Option<T> {
pub fn get_or_insert_default(&mut self) -> &mut T where T: Default;
}
Steps / History
- Original issue: #55042
- [x] Implementation: #82849
- [x] Renamed from
get_or_default
toget_or_insert_default
: #82977 - [ ] Final commenting period (FCP)
- [ ] Stabilization PR
Unresolved Questions
- None yet.
It's not obvious to me at all from the name that this modifies the Option
. It sounds like it'd be the same as unwrap_or_default
. Something like get_or_insert_default
would be more consistent with the other method names.
Hmm I hadn't considered that.
+1 on the name get_or_insert_default
I wanted to use this today, but it's still experimental. :laughing:
+1 -- was looking for this exact method today
@rustbot ping libs
Let's see if this works now? Would be nice to have this FCP'ed.
cc @joshtriplett
Error: Only Rust team members can ping teams.
Please file an issue on GitHub at triagebot if there's a problem with this bot, or reach out on #t-infra on Zulip.
LGTM
@rfcbot merge
Team member @joshtriplett has proposed to merge this. The next step is review by the rest of the tagged team members:
- [x] @Amanieu
- [ ] @BurntSushi
- [x] @dtolnay
- [x] @joshtriplett
- [x] @m-ou-se
- [ ] @yaahc
Concerns:
- is this in the same category as resize_default (https://github.com/rust-lang/rust/issues/82901#issuecomment-1244996427)
Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!
See this document for info about what commands tagged team members can give me.
:bell: This is now entering its final comment period, as per the review above. :bell:
@rfcbot concern is this in the same category as resize_default
Many years ago we deleted vec.resize_default(n)
because it just wasn't worth having when vec.resize_with(n, T::default)
is equally suitable.
- https://github.com/rust-lang/rust/issues/41758
- https://github.com/rust-lang/rust/pull/57656
- https://github.com/rust-lang/rust/pull/77850
It seems like it came down to just not being worth dedicating a whole new method given how rarely resize_with
is used in the first place. This is in contrast to option.unwrap_or_default()
as shorthand for option.unwrap_or_else(T::default)
, which is the only existing precedent for T::default
getting a dedicated convenience that I know of, and is justified by being used literally over 100× more than resize_with
.
I suppose option.get_or_insert_default()
is much closer to the resize_with
end of this spectrum than the unwrap_or_default
end, and option.get_or_insert_with(T::default)
would be good enough.
My own experience (which may or may not be representative) tells that in every single case I wanted option.get_or_insert_
-like functionality I actually wanted option.get_or_insert_default()
. So in my books it is much closer to unwrap_or_default
than to resize_with
. Just my 2 shekels.
Be aware that whether or not you want the default value is not the only consideration here. You also require a situation in which T
is completely inferrable. The combination of those 2 is less common in my experience (especially if I also take into account experience from similar situations in the Entry
API). Extrapolating "every single case I wanted the default" to "therefore I would have found get_or_insert_default valuable if available" is not correct.
use std::collections::BTreeSet;
use std::iter;
fn main() {
let mut junks = None;
for (id, value) in iter::repeat(("junk", 99)).take(10) {
if id == "junk" {
junks.get_or_insert_with(BTreeSet::default).insert(value);
}
}
println!("{:?}", junks);
}
With get_or_insert_default:
error[E0282]: type annotations needed for `Option<T>`
--> src/main.rs:5:9
|
5 | let mut junks = None;
| ^^^^^^^^^
...
8 | junks.get_or_insert_default().insert(value);
| ------ type must be known at this point
Very good example. However, in my opinion it doesn't lower the value of get_or_insert_default
. Just my opinion - I realize others can feel differently.
Is there anything blocking stabilisation of this?