-
Notifications
You must be signed in to change notification settings - Fork 13k
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 slice::replace
#76902
add slice::replace
#76902
Conversation
(rust_highfive has picked a reviewer for you, use r? to override) |
221bdf8
to
bcc9012
Compare
I first thought that the name might be slightly confusing, as Not a member of |
I would prefer to avoid this, as the name is "really nice" and the mem::replace seems relatively straightforward to reach for. Plus, I'd like for us to have https://doc.rust-lang.org/nightly/std/primitive.str.html#method.replace on slices eventually, and this addition would mean that we'd need another name for that... However, I am not on the libs team, so will defer to r? @KodrAus for final call here. |
Thanks for the PR! The other option would be to chat about it on URLO/Zulip, but for something where making an initial PR isn't a huge pain, personally I like just having it concrete to see.
I think swap is materially different, here. Replace is trivial to write with just safe code: fn myswap<T>(x: &mut[T], i: usize, j: usize) {
if i == j { return; }
let (i, j) = (i.min(j), i.max(j));
let (a, b) = x.split_at_mut(j);
std::mem::swap(&mut a[i], &mut b[0]);
} But there's no way that will codegen as well as the And since So I think I'm with Mark on this one -- though of course I'm not on libs either. |
/// assert_eq!(r, 2); | ||
/// ``` | ||
#[unstable(feature = "slice_replace", reason = "new API", issue = "none")] | ||
pub fn replace(&mut self, index: usize, value: T) -> T { |
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.
nit: don't bother making this change until we find out whether libs wants to move forward, but note that mem::replace
is must_use
, so this one probably should be too -- maybe something like
#[must_use = "if you don't need the old value, you can just assign the new value directly with `*slice[index] = value;`"]
There is a number of methods on slices already that can be written directly without
In terms of syntactic and cognitive overhead, I think I do see the argument that |
This, to me, is one of those places where something and its functional opposite can both be true. That statement is true, but it's also true that once you know both So I tend to weight it by what I'd rather see in a code review. And between
That one's interesting in that it's accidentally a great example of the kind of thing I meant by "a simpler precondition or anything either". It's actually equivalent to (And this is also an example of a place where |
My point being that these two things are relatively unconnected concepts that a newcomer to the language may have trouble making a mental connection between. In my experience, On the other hand, The point on parameter order is a bit moot given that the opposite really doesn't make as much sense. We already have You could argue that if you have a Using However, let mut vec = Vec::with_capacity(s.len());
vec.extend_from_slice(s);
vec and arguably the |
Thanks for the PR @izik1! There are definitely reasons to want to combine a few independently simple operations into a single more semantically readable one. Encapsulating Specifically for let old = mem::replace(&mut slice[i], new) is about as good as you can do. You could imagine someone working with let old = slice[i];
slice[i] = new; which generates equivalent code to So I think if we do want this then we should do some more exploration of how naive code attempting to replace an element within a slice could be improved by |
I agree with this argument, and it's what I thought the PR was adding before I read it. I also agree that the arguments might be unclear when this method is used:
Would it have the same effect to mention |
Triage: What's the current status here? |
Hi! Sorry for not coming back to this, I keep forgetting about it ^^; I think it would probably be fine to just close this, as I mentioned in the OP, it was a bit of a drive by and wasn't entirely sure if it was wanted so it wouldn't bother me much to close it, there are a lot of valid points raised about:
I'm not sure what proper PR protocol is here, so I'm going to just close? |
Hi! This is my first pr here and it's a bit of a drive by "what if libcore had a method I reach for sometimes."
I'm not really sure of all the things I'm supposed to be doing, however, I have tried copying how other contribution have been formatted to the best of my ability.
I haven't added any tests yet because I'm not entirely sure myself if this is something that's wanted in libcore.