-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Add try_remove
to Vec
#77480
Add try_remove
to Vec
#77480
Conversation
This provides a 'non-panicky' way of removing an element from a vector When the index exists, we return it; Otherwise, `None` is returned
r? @sfackler (rust_highfive has picked a reviewer for you, use r? to override) |
@rustbot modify labels to +A-collections |
@rustbot modify labels to +T-libs |
I really like the complexity of this error |
If we're adding this, should we also add |
I kinda agree. There should be non-panicky methods for methods that can panic, especially when a panic is expected. Now, if we have to enforce this |
Sure, that seems like a good place. Maybe near the existing tests for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
r=me on the implementation, but this should have someone from T-libs make sure this is a useful addition to the API that's on the roadmap.
r? @KodrAus |
This comment has been minimized.
This comment has been minimized.
It tells you if you scroll up:
|
This comment has been minimized.
This comment has been minimized.
@ohsayan It needs to go in |
I feel like this is a convention change to Vec, and thus needs more than just a PR. Because, as @timvermeulen mentioned, why is this just to The preconditions for the indexes on all these are simple enough to check yourself, so I don't think it's worth the API bloat to have non-panicking versions of all of them, and I don't think that any of them are special enough to have such a version when the others don't. That said, maybe it would make sense to have a fallible form of an API like #76885 that people could use to check bounds without panicking or hand-coding it? (For that conversation, maybe head over to #76393 (comment)?) Though I suppose (Note also that it took rust-lang/rfcs#2116 to add |
@scottmcm Maybe we should have had all these methods returning some kind of Edit: The only way to make all these functions non-panicking is post 2.x.y, which doesn't seem plausible enough to me, just for the sake of having fallible variants.
|
I'll be having some free time tomorrow; so I'll try and experiment with the possibilities of a convention change. Edit: FWIW, should we have a dedicated issue for this? |
This kind of thing comes up periodically, seemingly from a perspective of
I don't think those are all that useful as precedent here. As mentioned in my other post,
Remember to give LLVM appropriate credit here. The number of checks that appear in the source code isn't necessarily the number of checks that happen at runtime; just the opposite. For example, https://rust.godbolt.org/z/rPbGah pub fn looks_like_2_checks_actually_2_checks(x: &[i32]) -> i32 {
x[0] + x[1]
}
pub fn looks_like_2_checks_actually_1_check(x: &[i32]) -> i32 {
x[1] + x[0]
}
pub fn looks_like_3_checks_actually_1_check(x: &[i32]) -> i32 {
assert!(x.len() >= 2);
x[0] + x[1]
} Similarly, something like this https://rust.godbolt.org/z/559fWe fn my_remove<T>(v: &mut Vec<T>, i: usize) -> Option<T> {
v.get(i)?;
Some(v.remove(i))
} Also optimizes out the panic check and code path from Edit: I should clarify that I'm not saying that a |
From the discussion here — it seems like it'd be better if we left panic handling to the user |
I agree with @scottmcm here that if we want to add fallible versions of these methods on |
As per the discussion here and with consensus from the community (and project members), a single PR will not be enough for providing fallible alternatives for insert/remove/... ops in |
Thanks for exploring this @ohsayan! |
@ohsayan any updates on RFC? I highly prefer
I think this is not the problem of a |
@optozorax Heya, I didn't get enough time to look back into this, but I'll try and create an RFC once I do |
Hi, like many others (I believe) people I've also noticed the lack of non-panicking methods like please tell me if things like that already were discussed somewhere. let's take for example simple let v = vec![1, 2, 3];
v.get(1); // Some(2)
v.get(1)!; // 2
unsafe{
v.get(1); // blazing fast 2
}
v.get(4); // None
v.get(4)!; // panic, note exclamation mark
unsafe{
v.get(4);
} // blazing fast UB here a new operator is introduced, exclamation mark - it means we want to call a version of fn which is allowed to panic at runtime. how it would look like from perspective of method signature and definition - interesting question. impl<T> Vec<T>{
fn get(&self, index: usize) -> Option<&T>
{
if self.len() < usize{
None
} else {
Some(&self[index])
}
}
} although this code may be trivially converted (by compiler) to fn get(&self, index: usize)! -> &T
{
&self[index]
} (simply remove len check and "unwrap" desired value) //fallible method
fn get(&self, index: usize) -> Option<&T>
{
if self.len() < usize{
None
} else {
Some(&self[index])
}
}
//panicking method
fn get(&self, index: usize)! -> &T
{
&self[index]
}
unsafe fn get... something more advanced
} I'm aware of this p.s. probably it is a discussion for rust-lang/project-error-handling#49 |
Posting comments on a closed PR is not a good way to get them reviewed. An ACP, RFC, or post on internals.rust-lang.org is a better way to get feedback. |
@jyn514 thanks, didn't know that. |
This provides a 'non-panicky' way of removing an element from a vector. When the index exists, we return it; Otherwise,
None
is returned.Tracking issue: #77481