Closed
Description
Feature gate: #![feature(slice_take)]
Public API
impl<T> [T] {
fn split_off<'a, R: OneSidedRange<usize>>(self: &mut &'a Self, range: R) -> Option<&'a Self>;
fn split_off_mut<'a, R: OneSidedRange<usize>>(self: &mut &'a mut Self, range: R) -> Option<&'a mut Self>;
fn split_off_first<'a>(self: &mut &'a Self) -> Option<&'a T>;
fn split_off_first_mut<'a>(self: &mut &'a mut Self) -> Option<&'a mut T>;
fn split_off_last<'a>(self: &mut &'a Self) -> Option<&'a T>;
fn split_off_last_mut<'a>(self: &mut &'a mut Self) -> Option<&'a mut T>;
}
// core::ops
trait OneSidedRange<T: ?Sized>: RangeBounds<T> {}
impl<T> OneSidedRange<T> for RangeTo<T> where Self: RangeBounds<T>;
impl<T> OneSidedRange<T> for RangeFrom<T> where Self: RangeBounds<T>;
impl<T> OneSidedRange<T> for RangeToInclusive<T> where Self: RangeBounds<T>;
Activity
KodrAus commentedon Jul 30, 2020
m-ou-se commentedon Nov 28, 2020
SimonSapin commentedon Jan 31, 2022
https://doc.rust-lang.org/nightly/std/ops/trait.OneSidedRange.html links to #69780 which is closed. Either it should be reopened (and some details filled in) or
#[unstable]
attributes should be changed to point here instead, depending on whether it’s useful to trackOneSidedRange
separately.lilyball commentedon Apr 27, 2022
Can we implement
OneSidedRange
forRangeFull
as well? I'd like to be able to sayself.slice.take(..)
as a shorthand forstd::mem::swap(&mut self.slice, &[])
(or I suppose forself.slice.take(0..)
). This doesn't fit the namingOneSidedRange
or the description that says the range is unbounded on one side1, but I don't see any reason whyRangeFull
should not be usable here.Footnotes
Technically it doesn't say it has to be bounded on the other side, but it does list
..
as a non-compliant type. ↩andersk commentedon Nov 4, 2022
Perhaps also rename
OneSidedRange
toUnboundedRange
, in that case?safinaskar commentedon Jun 3, 2023
Please, rename. Method
take
is unusable with its current name, because it conflicts withstd::io::Read::take
.Let me describe my actual production use case.
First I read some data from file using
std::io::Read::read_to_end
. To be able to read data I have to writeuse std::io::Read
. Then I started to parse that data using various functions, including<[T]>::take
. But I was unable to do this because ofuse std::io::Read
, see playground: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=e467873898a5f160420a5d6f13274ffaclarfonthey commentedon Jun 5, 2023
FYI: #69780 is still being linked for
OneSideRange
in the docs when that issue is closed; should the tracking issue be moved to here?jongiddy commentedon Jul 1, 2023
I agree with @safinaskar that a different name for
take
(andtake_mut
) should be considered. I liketake_slice
andtake_slice_mut
for the current API.But changing the API to replace
take(range)
withtake_before(usize)
andtake_after(usize)
(and possiblytake_all()
) would be clearer and removes the need to resolve issues withOneSidedRange
.jongiddy commentedon Sep 25, 2023
I'd love to see taking from a slice stabilized. But the introduction of
OneSidedRange
seems to be the wrong path to take. I looked at the previous discussion for the benefits of addingOneSidedRange
. They are:OneSidedRange
did not solve the method naming problem, the original design withoutOneSidedRange
can also use regular indices rather than length from the end, and I don't see any other code that usesOneSidedRange
. The only objective benefit realized from the above is that the number of methods reduced from 8 to 6.Meanwhile the
OneSidedRange
code requires two match statements to turn the range parameter back into a single index and then call separate paths for the two possible directions. It also adds panic code for the unreachable variants when changing the range to an index and a direction.The benefits of
OneSidedRange
just do not justify the additional complexity, especially as part of the standard library.I propose the creation of a new implementation PR to remove
OneSidedRange
and replacetake
withtake_before
andtake_after
methods +_mut
variants. I'm happy to make the PR (but also happy for someone else to do it). But I'd like to check if anyone is strongly opposed first.cc @nox @cramertj @timvermeulen @ibraheemdev who worked on the previous implementation PR's.
WaffleLapkin commentedon Oct 2, 2023
@safinaskar this conflict is indeed very unfortunate, however do note that there are workarounds. Notably you can:
Read
trait in a different module or function (you can writeuse
inside a function) than the usage of the take method(&mut s).take(..1)
)<[_]>::take(&mut s, ..1)
)s.take(..1)
wheres
has type&mut &[_]
)See playground.
53 remaining items