Open
Description
Feature gate: #![feature(once_cell_try_insert)]
This is a tracking issue for OnceCell::try_insert()
and OnceLock::try_insert()
.
This adds a method similarly to OnceCell/Lock::set()
but returns a reference at the same time. This is also similar to OnceCell/Lock::get_or_init()
but the return value also tells you if the value was actually inserted or if the OnceCell/Lock
was already occupied.
Public API
impl<T> OnceCell<T> {
pub fn try_insert(&self, value: T) -> Result<&T, (&T, T)>;
}
Steps / History
- Implementation: Implement
OnceCell/Lock::try_insert()
#116540Final comment period (FCP)1Stabilization PR
Unresolved Questions
- None yet.
Footnotes
Metadata
Metadata
Assignees
Labels
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
OnceCell/Lock::try_insert()
#116540Rollup merge of rust-lang#116540 - daxpedda:once-cell-lock-try-insert…
Unrolled build for rust-lang#116540
ChayimFriedman2 commentedon Jan 3, 2024
Should the return type be
Result<&T, (&T, T)>
or(&T, Option<T>)
or(&T, Result<T, ()>)
? It is easier to use the(&T, Option<T>)
version but it does not encode the fact that there was a failure to insert ((&T, Result<T, ()>)
encodes this better, but still not as good asResult<&T, (&T, T)>
). On the other hand, the differences are not that significant since one is likely tomatch
or the result oftry_insert()
anyway, since fortry_insert().unwrap()
we have the betterset().unwrap()
.tisonkun commentedon Feb 26, 2024
I'm working on #121641 and wonder if we should add
&mut
both in the receiver and the result. Generally insert is a mutation and we can get a mut ref for the result if succeed.once_cell
dependency once the standard library provides it audunhalland/unimock#21Zollerboy1 commentedon Jun 16, 2024
Is there a reason, why this takes a value directly instead of an
FnOnce
likeget_or_init
and friends do?I would like to use this in a case where I have to know after a
get_or_init
if the call inserted a value or not, but with the current design it seems that I have to check withget
first to avoid creating a value that's not actually needed.daxpedda commentedon Jun 16, 2024
I'm unsure how I missed these comments but here goes:
Given that all these options fulfill the requirements, personally I'm still in favor of
Result<&T, (&T, T)>
because it seems to be the easiest to use.I'm assuming you mean adding new
&mut
APIs, because altering the ones proposed here would defeat its purpose.The only use case I know of is only valid if the value is shared, otherwise
get_or_try_init()
would cover it. So I'm unsure if a&mut
API addition would bring any value to the table in this case, seeing thatget_mut_or_try_init()
exists.That sounds quite reasonable to me, I will make a PR proposing this change when I get to it.
daxpedda commentedon Jun 17, 2024
While implementing it I realized that this is a bit different.
This API is more similar to
set()
, which takes a value as well. Taking a function would have different tradeoffs, e.g. any values owned by this function would be lost, users would have to use workarounds like this:So I think this would need another API addition.