pub struct IoSlice<'a>();
Expand description
A buffer type used with Write::write_vectored
.
It is semantically a wrapper around a &[u8]
, but is guaranteed to be ABI compatible with the iovec
type on Unix platforms and WSABUF
on Windows.
Creates a new IoSlice
wrapping a byte slice.
Panics on Windows if the slice is larger than 4GB.
1.81.0 · SourceAdvance the internal cursor of the slice.
Also see IoSlice::advance_slices
to advance the cursors of multiple buffers.
Panics when trying to advance beyond the end of the slice.
§Examplesuse std::io::IoSlice;
use std::ops::Deref;
let data = [1; 8];
let mut buf = IoSlice::new(&data);
buf.advance(3);
assert_eq!(buf.deref(), [1; 5].as_ref());
1.81.0 · Source
Advance a slice of slices.
Shrinks the slice to remove any IoSlice
s that are fully advanced over. If the cursor ends up in the middle of an IoSlice
, it is modified to start at that cursor.
For example, if we have a slice of two 8-byte IoSlice
s, and we advance by 10 bytes, the result will only include the second IoSlice
, advanced by 2 bytes.
Panics when trying to advance beyond the end of the slices.
§Examplesuse std::io::IoSlice;
use std::ops::Deref;
let buf1 = [1; 8];
let buf2 = [2; 16];
let buf3 = [3; 8];
let mut bufs = &mut [
IoSlice::new(&buf1),
IoSlice::new(&buf2),
IoSlice::new(&buf3),
][..];
IoSlice::advance_slices(&mut bufs, 10);
assert_eq!(bufs[0].deref(), [2; 14].as_ref());
assert_eq!(bufs[1].deref(), [3; 8].as_ref());
Source ð¬This is a nightly-only experimental API. (io_slice_as_bytes
#132818)
Get the underlying bytes as a slice with the original lifetime.
This doesnât borrow from self
, so is less restrictive than calling .deref()
, which does.
#![feature(io_slice_as_bytes)]
use std::io::IoSlice;
let data = b"abcdef";
let mut io_slice = IoSlice::new(data);
let tail = &io_slice.as_slice()[3..];
io_slice = IoSlice::new(tail);
assert_eq!(io_slice.as_slice(), b"def");
1.23.0 · Source
Checks if all bytes in this slice are within the ASCII range.
Source ð¬This is a nightly-only experimental API. (ascii_char
#110998)
If this slice is_ascii
, returns it as a slice of ASCII characters, otherwise returns None
.
ascii_char
#110998)
Converts this slice of bytes into a slice of ASCII characters, without checking whether theyâre valid.
§SafetyEvery byte in the slice must be in 0..=127
, or else this is UB.
Checks that two slices are an ASCII case-insensitive match.
Same as to_ascii_lowercase(a) == to_ascii_lowercase(b)
, but without allocating and copying temporaries.
Returns an iterator that produces an escaped version of this slice, treating it as an ASCII string.
§Exampleslet s = b"0\t\r\n'\"\\\x9d";
let escaped = s.escape_ascii().to_string();
assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d");
1.80.0 · Source
Returns a byte slice with leading ASCII whitespace bytes removed.
âWhitespaceâ refers to the definition used by u8::is_ascii_whitespace
.
assert_eq!(b" \t hello world\n".trim_ascii_start(), b"hello world\n");
assert_eq!(b" ".trim_ascii_start(), b"");
assert_eq!(b"".trim_ascii_start(), b"");
1.80.0 · Source
Returns a byte slice with trailing ASCII whitespace bytes removed.
âWhitespaceâ refers to the definition used by u8::is_ascii_whitespace
.
assert_eq!(b"\r hello world\n ".trim_ascii_end(), b"\r hello world");
assert_eq!(b" ".trim_ascii_end(), b"");
assert_eq!(b"".trim_ascii_end(), b"");
1.80.0 · Source
Returns a byte slice with leading and trailing ASCII whitespace bytes removed.
âWhitespaceâ refers to the definition used by u8::is_ascii_whitespace
.
assert_eq!(b"\r hello world\n ".trim_ascii(), b"hello world");
assert_eq!(b" ".trim_ascii(), b"");
assert_eq!(b"".trim_ascii(), b"");
1.0.0 · Source
Returns the number of elements in the slice.
§Exampleslet a = [1, 2, 3];
assert_eq!(a.len(), 3);
1.0.0 · Source
Returns true
if the slice has a length of 0.
let a = [1, 2, 3];
assert!(!a.is_empty());
let b: &[i32] = &[];
assert!(b.is_empty());
1.0.0 · Source
Returns the first element of the slice, or None
if it is empty.
let v = [10, 40, 30];
assert_eq!(Some(&10), v.first());
let w: &[i32] = &[];
assert_eq!(None, w.first());
1.5.0 · Source
Returns the first and all the rest of the elements of the slice, or None
if it is empty.
let x = &[0, 1, 2];
if let Some((first, elements)) = x.split_first() {
assert_eq!(first, &0);
assert_eq!(elements, &[1, 2]);
}
1.5.0 · Source
Returns the last and all the rest of the elements of the slice, or None
if it is empty.
let x = &[0, 1, 2];
if let Some((last, elements)) = x.split_last() {
assert_eq!(last, &2);
assert_eq!(elements, &[0, 1]);
}
1.0.0 · Source
Returns the last element of the slice, or None
if it is empty.
let v = [10, 40, 30];
assert_eq!(Some(&30), v.last());
let w: &[i32] = &[];
assert_eq!(None, w.last());
1.77.0 · Source
Returns an array reference to the first N
items in the slice.
If the slice is not at least N
in length, this will return None
.
let u = [10, 40, 30];
assert_eq!(Some(&[10, 40]), u.first_chunk::<2>());
let v: &[i32] = &[10];
assert_eq!(None, v.first_chunk::<2>());
let w: &[i32] = &[];
assert_eq!(Some(&[]), w.first_chunk::<0>());
1.77.0 · Source
Returns an array reference to the first N
items in the slice and the remaining slice.
If the slice is not at least N
in length, this will return None
.
let x = &[0, 1, 2];
if let Some((first, elements)) = x.split_first_chunk::<2>() {
assert_eq!(first, &[0, 1]);
assert_eq!(elements, &[2]);
}
assert_eq!(None, x.split_first_chunk::<4>());
1.77.0 · Source
Returns an array reference to the last N
items in the slice and the remaining slice.
If the slice is not at least N
in length, this will return None
.
let x = &[0, 1, 2];
if let Some((elements, last)) = x.split_last_chunk::<2>() {
assert_eq!(elements, &[0]);
assert_eq!(last, &[1, 2]);
}
assert_eq!(None, x.split_last_chunk::<4>());
1.77.0 · Source
Returns an array reference to the last N
items in the slice.
If the slice is not at least N
in length, this will return None
.
let u = [10, 40, 30];
assert_eq!(Some(&[40, 30]), u.last_chunk::<2>());
let v: &[i32] = &[10];
assert_eq!(None, v.last_chunk::<2>());
let w: &[i32] = &[];
assert_eq!(Some(&[]), w.last_chunk::<0>());
1.0.0 · Source
Returns a reference to an element or subslice depending on the type of index.
None
if out of bounds.None
if out of bounds.let v = [10, 40, 30];
assert_eq!(Some(&40), v.get(1));
assert_eq!(Some(&[10, 40][..]), v.get(0..2));
assert_eq!(None, v.get(3));
assert_eq!(None, v.get(0..4));
1.0.0 · Source
Returns a reference to an element or subslice, without doing bounds checking.
For a safe alternative see get
.
Calling this method with an out-of-bounds index is undefined behavior even if the resulting reference is not used.
You can think of this like .get(index).unwrap_unchecked()
. Itâs UB to call .get_unchecked(len)
, even if you immediately convert to a pointer. And itâs UB to call .get_unchecked(..len + 1)
, .get_unchecked(..=len)
, or similar.
let x = &[1, 2, 4];
unsafe {
assert_eq!(x.get_unchecked(1), &2);
}
1.0.0 · Source
Returns a raw pointer to the sliceâs buffer.
The caller must ensure that the slice outlives the pointer this function returns, or else it will end up dangling.
The caller must also ensure that the memory the pointer (non-transitively) points to is never written to (except inside an UnsafeCell
) using this pointer or any pointer derived from it. If you need to mutate the contents of the slice, use as_mut_ptr
.
Modifying the container referenced by this slice may cause its buffer to be reallocated, which would also make any pointers to it invalid.
§Exampleslet x = &[1, 2, 4];
let x_ptr = x.as_ptr();
unsafe {
for i in 0..x.len() {
assert_eq!(x.get_unchecked(i), &*x_ptr.add(i));
}
}
1.48.0 · Source
Returns the two raw pointers spanning the slice.
The returned range is half-open, which means that the end pointer points one past the last element of the slice. This way, an empty slice is represented by two equal pointers, and the difference between the two pointers represents the size of the slice.
See as_ptr
for warnings on using these pointers. The end pointer requires extra caution, as it does not point to a valid element in the slice.
This function is useful for interacting with foreign interfaces which use two pointers to refer to a range of elements in memory, as is common in C++.
It can also be useful to check if a pointer to an element refers to an element of this slice:
let a = [1, 2, 3];
let x = &a[1] as *const _;
let y = &5 as *const _;
assert!(a.as_ptr_range().contains(&x));
assert!(!a.as_ptr_range().contains(&y));
Source ð¬This is a nightly-only experimental API. (slice_as_array
#133508)
Gets a reference to the underlying array.
If N
is not exactly equal to the length of self
, then this method returns None
.
Returns an iterator over the slice.
The iterator yields all items from start to end.
§Exampleslet x = &[1, 2, 4];
let mut iterator = x.iter();
assert_eq!(iterator.next(), Some(&1));
assert_eq!(iterator.next(), Some(&2));
assert_eq!(iterator.next(), Some(&4));
assert_eq!(iterator.next(), None);
1.0.0 · Source
Returns an iterator over all contiguous windows of length size
. The windows overlap. If the slice is shorter than size
, the iterator returns no values.
Panics if size
is zero.
let slice = ['l', 'o', 'r', 'e', 'm'];
let mut iter = slice.windows(3);
assert_eq!(iter.next().unwrap(), &['l', 'o', 'r']);
assert_eq!(iter.next().unwrap(), &['o', 'r', 'e']);
assert_eq!(iter.next().unwrap(), &['r', 'e', 'm']);
assert!(iter.next().is_none());
If the slice is shorter than size
:
let slice = ['f', 'o', 'o'];
let mut iter = slice.windows(4);
assert!(iter.next().is_none());
Because the Iterator trait cannot represent the required lifetimes, there is no windows_mut
analog to windows
; [0,1,2].windows_mut(2).collect()
would violate the rules of references (though a LendingIterator analog is possible). You can sometimes use Cell::as_slice_of_cells
in conjunction with windows
instead:
use std::cell::Cell;
let mut array = ['R', 'u', 's', 't', ' ', '2', '0', '1', '5'];
let slice = &mut array[..];
let slice_of_cells: &[Cell<char>] = Cell::from_mut(slice).as_slice_of_cells();
for w in slice_of_cells.windows(3) {
Cell::swap(&w[0], &w[2]);
}
assert_eq!(array, ['s', 't', ' ', '2', '0', '1', '5', 'u', 'R']);
1.0.0 · Source
Returns an iterator over chunk_size
elements of the slice at a time, starting at the beginning of the slice.
The chunks are slices and do not overlap. If chunk_size
does not divide the length of the slice, then the last chunk will not have length chunk_size
.
See chunks_exact
for a variant of this iterator that returns chunks of always exactly chunk_size
elements, and rchunks
for the same iterator but starting at the end of the slice.
Panics if chunk_size
is zero.
let slice = ['l', 'o', 'r', 'e', 'm'];
let mut iter = slice.chunks(2);
assert_eq!(iter.next().unwrap(), &['l', 'o']);
assert_eq!(iter.next().unwrap(), &['r', 'e']);
assert_eq!(iter.next().unwrap(), &['m']);
assert!(iter.next().is_none());
1.31.0 · Source
Returns an iterator over chunk_size
elements of the slice at a time, starting at the beginning of the slice.
The chunks are slices and do not overlap. If chunk_size
does not divide the length of the slice, then the last up to chunk_size-1
elements will be omitted and can be retrieved from the remainder
function of the iterator.
Due to each chunk having exactly chunk_size
elements, the compiler can often optimize the resulting code better than in the case of chunks
.
See chunks
for a variant of this iterator that also returns the remainder as a smaller chunk, and rchunks_exact
for the same iterator but starting at the end of the slice.
Panics if chunk_size
is zero.
let slice = ['l', 'o', 'r', 'e', 'm'];
let mut iter = slice.chunks_exact(2);
assert_eq!(iter.next().unwrap(), &['l', 'o']);
assert_eq!(iter.next().unwrap(), &['r', 'e']);
assert!(iter.next().is_none());
assert_eq!(iter.remainder(), &['m']);
1.88.0 · Source
Splits the slice into a slice of N
-element arrays, assuming that thereâs no remainder.
This is the inverse operation to as_flattened
.
As this is unsafe
, consider whether you could use as_chunks
or as_rchunks
instead, perhaps via something like if let (chunks, []) = slice.as_chunks()
or let (chunks, []) = slice.as_chunks() else { unreachable!() };
.
This may only be called when
N
-element chunks (aka self.len() % N == 0
).N != 0
.let slice: &[char] = &['l', 'o', 'r', 'e', 'm', '!'];
let chunks: &[[char; 1]] =
unsafe { slice.as_chunks_unchecked() };
assert_eq!(chunks, &[['l'], ['o'], ['r'], ['e'], ['m'], ['!']]);
let chunks: &[[char; 3]] =
unsafe { slice.as_chunks_unchecked() };
assert_eq!(chunks, &[['l', 'o', 'r'], ['e', 'm', '!']]);
1.88.0 · Source
Splits the slice into a slice of N
-element arrays, starting at the beginning of the slice, and a remainder slice with length strictly less than N
.
The remainder is meaningful in the division sense. Given let (chunks, remainder) = slice.as_chunks()
, then:
chunks.len()
equals slice.len() / N
,remainder.len()
equals slice.len() % N
, andslice.len()
equals chunks.len() * N + remainder.len()
.You can flatten the chunks back into a slice-of-T
with as_flattened
.
Panics if N
is zero.
Note that this check is against a const generic parameter, not a runtime value, and thus a particular monomorphization will either always panic or it will never panic.
§Exampleslet slice = ['l', 'o', 'r', 'e', 'm'];
let (chunks, remainder) = slice.as_chunks();
assert_eq!(chunks, &[['l', 'o'], ['r', 'e']]);
assert_eq!(remainder, &['m']);
If you expect the slice to be an exact multiple, you can combine let
-else
with an empty slice pattern:
let slice = ['R', 'u', 's', 't'];
let (chunks, []) = slice.as_chunks::<2>() else {
panic!("slice didn't have even length")
};
assert_eq!(chunks, &[['R', 'u'], ['s', 't']]);
1.88.0 · Source
Splits the slice into a slice of N
-element arrays, starting at the end of the slice, and a remainder slice with length strictly less than N
.
The remainder is meaningful in the division sense. Given let (remainder, chunks) = slice.as_rchunks()
, then:
remainder.len()
equals slice.len() % N
,chunks.len()
equals slice.len() / N
, andslice.len()
equals chunks.len() * N + remainder.len()
.You can flatten the chunks back into a slice-of-T
with as_flattened
.
Panics if N
is zero.
Note that this check is against a const generic parameter, not a runtime value, and thus a particular monomorphization will either always panic or it will never panic.
§Exampleslet slice = ['l', 'o', 'r', 'e', 'm'];
let (remainder, chunks) = slice.as_rchunks();
assert_eq!(remainder, &['l']);
assert_eq!(chunks, &[['o', 'r'], ['e', 'm']]);
Source ð¬This is a nightly-only experimental API. (array_chunks
#74985)
Returns an iterator over N
elements of the slice at a time, starting at the beginning of the slice.
The chunks are array references and do not overlap. If N
does not divide the length of the slice, then the last up to N-1
elements will be omitted and can be retrieved from the remainder
function of the iterator.
This method is the const generic equivalent of chunks_exact
.
Panics if N
is zero. This check will most probably get changed to a compile time error before this method gets stabilized.
#![feature(array_chunks)]
let slice = ['l', 'o', 'r', 'e', 'm'];
let mut iter = slice.array_chunks();
assert_eq!(iter.next().unwrap(), &['l', 'o']);
assert_eq!(iter.next().unwrap(), &['r', 'e']);
assert!(iter.next().is_none());
assert_eq!(iter.remainder(), &['m']);
Source ð¬This is a nightly-only experimental API. (array_windows
#75027)
Returns an iterator over overlapping windows of N
elements of a slice, starting at the beginning of the slice.
This is the const generic equivalent of windows
.
If N
is greater than the size of the slice, it will return no windows.
Panics if N
is zero. This check will most probably get changed to a compile time error before this method gets stabilized.
#![feature(array_windows)]
let slice = [0, 1, 2, 3];
let mut iter = slice.array_windows();
assert_eq!(iter.next().unwrap(), &[0, 1]);
assert_eq!(iter.next().unwrap(), &[1, 2]);
assert_eq!(iter.next().unwrap(), &[2, 3]);
assert!(iter.next().is_none());
1.31.0 · Source
Returns an iterator over chunk_size
elements of the slice at a time, starting at the end of the slice.
The chunks are slices and do not overlap. If chunk_size
does not divide the length of the slice, then the last chunk will not have length chunk_size
.
See rchunks_exact
for a variant of this iterator that returns chunks of always exactly chunk_size
elements, and chunks
for the same iterator but starting at the beginning of the slice.
Panics if chunk_size
is zero.
let slice = ['l', 'o', 'r', 'e', 'm'];
let mut iter = slice.rchunks(2);
assert_eq!(iter.next().unwrap(), &['e', 'm']);
assert_eq!(iter.next().unwrap(), &['o', 'r']);
assert_eq!(iter.next().unwrap(), &['l']);
assert!(iter.next().is_none());
1.31.0 · Source
Returns an iterator over chunk_size
elements of the slice at a time, starting at the end of the slice.
The chunks are slices and do not overlap. If chunk_size
does not divide the length of the slice, then the last up to chunk_size-1
elements will be omitted and can be retrieved from the remainder
function of the iterator.
Due to each chunk having exactly chunk_size
elements, the compiler can often optimize the resulting code better than in the case of rchunks
.
See rchunks
for a variant of this iterator that also returns the remainder as a smaller chunk, and chunks_exact
for the same iterator but starting at the beginning of the slice.
Panics if chunk_size
is zero.
let slice = ['l', 'o', 'r', 'e', 'm'];
let mut iter = slice.rchunks_exact(2);
assert_eq!(iter.next().unwrap(), &['e', 'm']);
assert_eq!(iter.next().unwrap(), &['o', 'r']);
assert!(iter.next().is_none());
assert_eq!(iter.remainder(), &['l']);
1.77.0 · Source
Returns an iterator over the slice producing non-overlapping runs of elements using the predicate to separate them.
The predicate is called for every pair of consecutive elements, meaning that it is called on slice[0]
and slice[1]
, followed by slice[1]
and slice[2]
, and so on.
let slice = &[1, 1, 1, 3, 3, 2, 2, 2];
let mut iter = slice.chunk_by(|a, b| a == b);
assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
assert_eq!(iter.next(), Some(&[3, 3][..]));
assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
assert_eq!(iter.next(), None);
This method can be used to extract the sorted subslices:
let slice = &[1, 1, 2, 3, 2, 3, 2, 3, 4];
let mut iter = slice.chunk_by(|a, b| a <= b);
assert_eq!(iter.next(), Some(&[1, 1, 2, 3][..]));
assert_eq!(iter.next(), Some(&[2, 3][..]));
assert_eq!(iter.next(), Some(&[2, 3, 4][..]));
assert_eq!(iter.next(), None);
1.0.0 · Source
Divides one slice into two at an index.
The first will contain all indices from [0, mid)
(excluding the index mid
itself) and the second will contain all indices from [mid, len)
(excluding the index len
itself).
Panics if mid > len
. For a non-panicking alternative see split_at_checked
.
let v = ['a', 'b', 'c'];
{
let (left, right) = v.split_at(0);
assert_eq!(left, []);
assert_eq!(right, ['a', 'b', 'c']);
}
{
let (left, right) = v.split_at(2);
assert_eq!(left, ['a', 'b']);
assert_eq!(right, ['c']);
}
{
let (left, right) = v.split_at(3);
assert_eq!(left, ['a', 'b', 'c']);
assert_eq!(right, []);
}
1.79.0 · Source
Divides one slice into two at an index, without doing bounds checking.
The first will contain all indices from [0, mid)
(excluding the index mid
itself) and the second will contain all indices from [mid, len)
(excluding the index len
itself).
For a safe alternative see split_at
.
Calling this method with an out-of-bounds index is undefined behavior even if the resulting reference is not used. The caller has to ensure that 0 <= mid <= self.len()
.
let v = ['a', 'b', 'c'];
unsafe {
let (left, right) = v.split_at_unchecked(0);
assert_eq!(left, []);
assert_eq!(right, ['a', 'b', 'c']);
}
unsafe {
let (left, right) = v.split_at_unchecked(2);
assert_eq!(left, ['a', 'b']);
assert_eq!(right, ['c']);
}
unsafe {
let (left, right) = v.split_at_unchecked(3);
assert_eq!(left, ['a', 'b', 'c']);
assert_eq!(right, []);
}
1.80.0 · Source
Divides one slice into two at an index, returning None
if the slice is too short.
If mid ⤠len
returns a pair of slices where the first will contain all indices from [0, mid)
(excluding the index mid
itself) and the second will contain all indices from [mid, len)
(excluding the index len
itself).
Otherwise, if mid > len
, returns None
.
let v = [1, -2, 3, -4, 5, -6];
{
let (left, right) = v.split_at_checked(0).unwrap();
assert_eq!(left, []);
assert_eq!(right, [1, -2, 3, -4, 5, -6]);
}
{
let (left, right) = v.split_at_checked(2).unwrap();
assert_eq!(left, [1, -2]);
assert_eq!(right, [3, -4, 5, -6]);
}
{
let (left, right) = v.split_at_checked(6).unwrap();
assert_eq!(left, [1, -2, 3, -4, 5, -6]);
assert_eq!(right, []);
}
assert_eq!(None, v.split_at_checked(7));
1.0.0 · Source
Returns an iterator over subslices separated by elements that match pred
. The matched element is not contained in the subslices.
let slice = [10, 40, 33, 20];
let mut iter = slice.split(|num| num % 3 == 0);
assert_eq!(iter.next().unwrap(), &[10, 40]);
assert_eq!(iter.next().unwrap(), &[20]);
assert!(iter.next().is_none());
If the first element is matched, an empty slice will be the first item returned by the iterator. Similarly, if the last element in the slice is matched, an empty slice will be the last item returned by the iterator:
let slice = [10, 40, 33];
let mut iter = slice.split(|num| num % 3 == 0);
assert_eq!(iter.next().unwrap(), &[10, 40]);
assert_eq!(iter.next().unwrap(), &[]);
assert!(iter.next().is_none());
If two matched elements are directly adjacent, an empty slice will be present between them:
let slice = [10, 6, 33, 20];
let mut iter = slice.split(|num| num % 3 == 0);
assert_eq!(iter.next().unwrap(), &[10]);
assert_eq!(iter.next().unwrap(), &[]);
assert_eq!(iter.next().unwrap(), &[20]);
assert!(iter.next().is_none());
1.51.0 · Source
Returns an iterator over subslices separated by elements that match pred
. The matched element is contained in the end of the previous subslice as a terminator.
let slice = [10, 40, 33, 20];
let mut iter = slice.split_inclusive(|num| num % 3 == 0);
assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
assert_eq!(iter.next().unwrap(), &[20]);
assert!(iter.next().is_none());
If the last element of the slice is matched, that element will be considered the terminator of the preceding slice. That slice will be the last item returned by the iterator.
let slice = [3, 10, 40, 33];
let mut iter = slice.split_inclusive(|num| num % 3 == 0);
assert_eq!(iter.next().unwrap(), &[3]);
assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
assert!(iter.next().is_none());
1.27.0 · Source
Returns an iterator over subslices separated by elements that match pred
, starting at the end of the slice and working backwards. The matched element is not contained in the subslices.
let slice = [11, 22, 33, 0, 44, 55];
let mut iter = slice.rsplit(|num| *num == 0);
assert_eq!(iter.next().unwrap(), &[44, 55]);
assert_eq!(iter.next().unwrap(), &[11, 22, 33]);
assert_eq!(iter.next(), None);
As with split()
, if the first or last element is matched, an empty slice will be the first (or last) item returned by the iterator.
let v = &[0, 1, 1, 2, 3, 5, 8];
let mut it = v.rsplit(|n| *n % 2 == 0);
assert_eq!(it.next().unwrap(), &[]);
assert_eq!(it.next().unwrap(), &[3, 5]);
assert_eq!(it.next().unwrap(), &[1, 1]);
assert_eq!(it.next().unwrap(), &[]);
assert_eq!(it.next(), None);
1.0.0 · Source
Returns an iterator over subslices separated by elements that match pred
, limited to returning at most n
items. The matched element is not contained in the subslices.
The last element returned, if any, will contain the remainder of the slice.
§ExamplesPrint the slice split once by numbers divisible by 3 (i.e., [10, 40]
, [20, 60, 50]
):
let v = [10, 40, 30, 20, 60, 50];
for group in v.splitn(2, |num| *num % 3 == 0) {
println!("{group:?}");
}
1.0.0 · Source
Returns an iterator over subslices separated by elements that match pred
limited to returning at most n
items. This starts at the end of the slice and works backwards. The matched element is not contained in the subslices.
The last element returned, if any, will contain the remainder of the slice.
§ExamplesPrint the slice split once, starting from the end, by numbers divisible by 3 (i.e., [50]
, [10, 40, 30, 20]
):
let v = [10, 40, 30, 20, 60, 50];
for group in v.rsplitn(2, |num| *num % 3 == 0) {
println!("{group:?}");
}
Source ð¬This is a nightly-only experimental API. (slice_split_once
#112811)
Splits the slice on the first element that matches the specified predicate.
If any matching elements are present in the slice, returns the prefix before the match and suffix after. The matching element itself is not included. If no elements match, returns None
.
#![feature(slice_split_once)]
let s = [1, 2, 3, 2, 4];
assert_eq!(s.split_once(|&x| x == 2), Some((
&[1][..],
&[3, 2, 4][..]
)));
assert_eq!(s.split_once(|&x| x == 0), None);
Source ð¬This is a nightly-only experimental API. (slice_split_once
#112811)
Splits the slice on the last element that matches the specified predicate.
If any matching elements are present in the slice, returns the prefix before the match and suffix after. The matching element itself is not included. If no elements match, returns None
.
#![feature(slice_split_once)]
let s = [1, 2, 3, 2, 4];
assert_eq!(s.rsplit_once(|&x| x == 2), Some((
&[1, 2, 3][..],
&[4][..]
)));
assert_eq!(s.rsplit_once(|&x| x == 0), None);
1.0.0 · Source
Returns true
if the slice contains an element with the given value.
This operation is O(n).
Note that if you have a sorted slice, binary_search
may be faster.
let v = [10, 40, 30];
assert!(v.contains(&30));
assert!(!v.contains(&50));
If you do not have a &T
, but some other value that you can compare with one (for example, String
implements PartialEq<str>
), you can use iter().any
:
let v = [String::from("hello"), String::from("world")]; assert!(v.iter().any(|e| e == "hello")); assert!(!v.iter().any(|e| e == "hi"));
1.0.0 · Source
Returns true
if needle
is a prefix of the slice or equal to the slice.
let v = [10, 40, 30];
assert!(v.starts_with(&[10]));
assert!(v.starts_with(&[10, 40]));
assert!(v.starts_with(&v));
assert!(!v.starts_with(&[50]));
assert!(!v.starts_with(&[10, 50]));
Always returns true
if needle
is an empty slice:
let v = &[10, 40, 30];
assert!(v.starts_with(&[]));
let v: &[u8] = &[];
assert!(v.starts_with(&[]));
1.0.0 · Source
Returns true
if needle
is a suffix of the slice or equal to the slice.
let v = [10, 40, 30];
assert!(v.ends_with(&[30]));
assert!(v.ends_with(&[40, 30]));
assert!(v.ends_with(&v));
assert!(!v.ends_with(&[50]));
assert!(!v.ends_with(&[50, 30]));
Always returns true
if needle
is an empty slice:
let v = &[10, 40, 30];
assert!(v.ends_with(&[]));
let v: &[u8] = &[];
assert!(v.ends_with(&[]));
1.51.0 · Source
Returns a subslice with the prefix removed.
If the slice starts with prefix
, returns the subslice after the prefix, wrapped in Some
. If prefix
is empty, simply returns the original slice. If prefix
is equal to the original slice, returns an empty slice.
If the slice does not start with prefix
, returns None
.
let v = &[10, 40, 30];
assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..]));
assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..]));
assert_eq!(v.strip_prefix(&[10, 40, 30]), Some(&[][..]));
assert_eq!(v.strip_prefix(&[50]), None);
assert_eq!(v.strip_prefix(&[10, 50]), None);
let prefix : &str = "he";
assert_eq!(b"hello".strip_prefix(prefix.as_bytes()),
Some(b"llo".as_ref()));
1.51.0 · Source
Returns a subslice with the suffix removed.
If the slice ends with suffix
, returns the subslice before the suffix, wrapped in Some
. If suffix
is empty, simply returns the original slice. If suffix
is equal to the original slice, returns an empty slice.
If the slice does not end with suffix
, returns None
.
let v = &[10, 40, 30];
assert_eq!(v.strip_suffix(&[30]), Some(&[10, 40][..]));
assert_eq!(v.strip_suffix(&[40, 30]), Some(&[10][..]));
assert_eq!(v.strip_suffix(&[10, 40, 30]), Some(&[][..]));
assert_eq!(v.strip_suffix(&[50]), None);
assert_eq!(v.strip_suffix(&[50, 30]), None);
Source ð¬This is a nightly-only experimental API. (trim_prefix_suffix
#142312)
Returns a subslice with the optional prefix removed.
If the slice starts with prefix
, returns the subslice after the prefix. If prefix
is empty or the slice does not start with prefix
, simply returns the original slice. If prefix
is equal to the original slice, returns an empty slice.
#![feature(trim_prefix_suffix)]
let v = &[10, 40, 30];
assert_eq!(v.trim_prefix(&[10]), &[40, 30][..]);
assert_eq!(v.trim_prefix(&[10, 40]), &[30][..]);
assert_eq!(v.trim_prefix(&[10, 40, 30]), &[][..]);
assert_eq!(v.trim_prefix(&[50]), &[10, 40, 30][..]);
assert_eq!(v.trim_prefix(&[10, 50]), &[10, 40, 30][..]);
let prefix : &str = "he";
assert_eq!(b"hello".trim_prefix(prefix.as_bytes()), b"llo".as_ref());
Source ð¬This is a nightly-only experimental API. (trim_prefix_suffix
#142312)
Returns a subslice with the optional suffix removed.
If the slice ends with suffix
, returns the subslice before the suffix. If suffix
is empty or the slice does not end with suffix
, simply returns the original slice. If suffix
is equal to the original slice, returns an empty slice.
#![feature(trim_prefix_suffix)]
let v = &[10, 40, 30];
assert_eq!(v.trim_suffix(&[30]), &[10, 40][..]);
assert_eq!(v.trim_suffix(&[40, 30]), &[10][..]);
assert_eq!(v.trim_suffix(&[10, 40, 30]), &[][..]);
assert_eq!(v.trim_suffix(&[50]), &[10, 40, 30][..]);
assert_eq!(v.trim_suffix(&[50, 30]), &[10, 40, 30][..]);
1.0.0 · Source
Binary searches this slice for a given element. If the slice is not sorted, the returned result is unspecified and meaningless.
If the value is found then Result::Ok
is returned, containing the index of the matching element. If there are multiple matches, then any one of the matches could be returned. The index is chosen deterministically, but is subject to change in future versions of Rust. If the value is not found then Result::Err
is returned, containing the index where a matching element could be inserted while maintaining sorted order.
See also binary_search_by
, binary_search_by_key
, and partition_point
.
Looks up a series of four elements. The first is found, with a uniquely determined position; the second and third are not found; the fourth could match any position in [1, 4]
.
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
assert_eq!(s.binary_search(&13), Ok(9));
assert_eq!(s.binary_search(&4), Err(7));
assert_eq!(s.binary_search(&100), Err(13));
let r = s.binary_search(&1);
assert!(match r { Ok(1..=4) => true, _ => false, });
If you want to find that whole range of matching items, rather than an arbitrary matching one, that can be done using partition_point
:
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
let low = s.partition_point(|x| x < &1);
assert_eq!(low, 1);
let high = s.partition_point(|x| x <= &1);
assert_eq!(high, 5);
let r = s.binary_search(&1);
assert!((low..high).contains(&r.unwrap()));
assert!(s[..low].iter().all(|&x| x < 1));
assert!(s[low..high].iter().all(|&x| x == 1));
assert!(s[high..].iter().all(|&x| x > 1));
assert_eq!(s.partition_point(|x| x < &11), 9);
assert_eq!(s.partition_point(|x| x <= &11), 9);
assert_eq!(s.binary_search(&11), Err(9));
If you want to insert an item to a sorted vector, while maintaining sort order, consider using partition_point
:
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
let num = 42;
let idx = s.partition_point(|&x| x <= num);
s.insert(idx, num);
assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
1.0.0 · Source
Binary searches this slice with a comparator function.
The comparator function should return an order code that indicates whether its argument is Less
, Equal
or Greater
the desired target. If the slice is not sorted or if the comparator function does not implement an order consistent with the sort order of the underlying slice, the returned result is unspecified and meaningless.
If the value is found then Result::Ok
is returned, containing the index of the matching element. If there are multiple matches, then any one of the matches could be returned. The index is chosen deterministically, but is subject to change in future versions of Rust. If the value is not found then Result::Err
is returned, containing the index where a matching element could be inserted while maintaining sorted order.
See also binary_search
, binary_search_by_key
, and partition_point
.
Looks up a series of four elements. The first is found, with a uniquely determined position; the second and third are not found; the fourth could match any position in [1, 4]
.
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
let seek = 13;
assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
let seek = 4;
assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7));
let seek = 100;
assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
let seek = 1;
let r = s.binary_search_by(|probe| probe.cmp(&seek));
assert!(match r { Ok(1..=4) => true, _ => false, });
1.10.0 · Source
Binary searches this slice with a key extraction function.
Assumes that the slice is sorted by the key, for instance with sort_by_key
using the same key extraction function. If the slice is not sorted by the key, the returned result is unspecified and meaningless.
If the value is found then Result::Ok
is returned, containing the index of the matching element. If there are multiple matches, then any one of the matches could be returned. The index is chosen deterministically, but is subject to change in future versions of Rust. If the value is not found then Result::Err
is returned, containing the index where a matching element could be inserted while maintaining sorted order.
See also binary_search
, binary_search_by
, and partition_point
.
Looks up a series of four elements in a slice of pairs sorted by their second elements. The first is found, with a uniquely determined position; the second and third are not found; the fourth could match any position in [1, 4]
.
let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
(1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
(1, 21), (2, 34), (4, 55)];
assert_eq!(s.binary_search_by_key(&13, |&(a, b)| b), Ok(9));
assert_eq!(s.binary_search_by_key(&4, |&(a, b)| b), Err(7));
assert_eq!(s.binary_search_by_key(&100, |&(a, b)| b), Err(13));
let r = s.binary_search_by_key(&1, |&(a, b)| b);
assert!(match r { Ok(1..=4) => true, _ => false, });
1.30.0 · Source
Transmutes the slice to a slice of another type, ensuring alignment of the types is maintained.
This method splits the slice into three distinct slices: prefix, correctly aligned middle slice of a new type, and the suffix slice. The middle part will be as big as possible under the given alignment constraint and element size.
This method has no purpose when either input element T
or output element U
are zero-sized and will return the original slice without splitting anything.
This method is essentially a transmute
with respect to the elements in the returned middle slice, so all the usual caveats pertaining to transmute::<T, U>
also apply here.
Basic usage:
unsafe {
let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
let (prefix, shorts, suffix) = bytes.align_to::<u16>();
}
Source ð¬This is a nightly-only experimental API. (portable_simd
#86656)
Splits a slice into a prefix, a middle of aligned SIMD types, and a suffix.
This is a safe wrapper around slice::align_to
, so inherits the same guarantees as that method.
This will panic if the size of the SIMD type is different from LANES
times that of the scalar.
At the time of writing, the trait restrictions on Simd<T, LANES>
keeps that from ever happening, as only power-of-two numbers of lanes are supported. Itâs possible that, in the future, those restrictions might be lifted in a way that would make it possible to see panics from this method for something like LANES == 3
.
#![feature(portable_simd)]
use core::simd::prelude::*;
let short = &[1, 2, 3];
let (prefix, middle, suffix) = short.as_simd::<4>();
assert_eq!(middle, []); let it = prefix.iter().chain(suffix).copied();
assert_eq!(it.collect::<Vec<_>>(), vec![1, 2, 3]);
fn basic_simd_sum(x: &[f32]) -> f32 {
use std::ops::Add;
let (prefix, middle, suffix) = x.as_simd();
let sums = f32x4::from_array([
prefix.iter().copied().sum(),
0.0,
0.0,
suffix.iter().copied().sum(),
]);
let sums = middle.iter().copied().fold(sums, f32x4::add);
sums.reduce_sum()
}
let numbers: Vec<f32> = (1..101).map(|x| x as _).collect();
assert_eq!(basic_simd_sum(&numbers[1..99]), 4949.0);
1.82.0 · Source
Checks if the elements of this slice are sorted.
That is, for each element a
and its following element b
, a <= b
must hold. If the slice yields exactly zero or one element, true
is returned.
Note that if Self::Item
is only PartialOrd
, but not Ord
, the above definition implies that this function returns false
if any two consecutive items are not comparable.
let empty: [i32; 0] = [];
assert!([1, 2, 2, 9].is_sorted());
assert!(![1, 3, 2, 4].is_sorted());
assert!([0].is_sorted());
assert!(empty.is_sorted());
assert!(![0.0, 1.0, f32::NAN].is_sorted());
1.82.0 · Source
Checks if the elements of this slice are sorted using the given comparator function.
Instead of using PartialOrd::partial_cmp
, this function uses the given compare
function to determine whether two elements are to be considered in sorted order.
assert!([1, 2, 2, 9].is_sorted_by(|a, b| a <= b));
assert!(![1, 2, 2, 9].is_sorted_by(|a, b| a < b));
assert!([0].is_sorted_by(|a, b| true));
assert!([0].is_sorted_by(|a, b| false));
let empty: [i32; 0] = [];
assert!(empty.is_sorted_by(|a, b| false));
assert!(empty.is_sorted_by(|a, b| true));
1.82.0 · Source
Checks if the elements of this slice are sorted using the given key extraction function.
Instead of comparing the sliceâs elements directly, this function compares the keys of the elements, as determined by f
. Apart from that, itâs equivalent to is_sorted
; see its documentation for more information.
assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
1.52.0 · Source
Returns the index of the partition point according to the given predicate (the index of the first element of the second partition).
The slice is assumed to be partitioned according to the given predicate. This means that all elements for which the predicate returns true are at the start of the slice and all elements for which the predicate returns false are at the end. For example, [7, 15, 3, 5, 4, 12, 6]
is partitioned under the predicate x % 2 != 0
(all odd numbers are at the start, all even at the end).
If this slice is not partitioned, the returned result is unspecified and meaningless, as this method performs a kind of binary search.
See also binary_search
, binary_search_by
, and binary_search_by_key
.
let v = [1, 2, 3, 3, 5, 6, 7];
let i = v.partition_point(|&x| x < 5);
assert_eq!(i, 4);
assert!(v[..i].iter().all(|&x| x < 5));
assert!(v[i..].iter().all(|&x| !(x < 5)));
If all elements of the slice match the predicate, including if the slice is empty, then the length of the slice will be returned:
let a = [2, 4, 8];
assert_eq!(a.partition_point(|x| x < &100), a.len());
let a: [i32; 0] = [];
assert_eq!(a.partition_point(|x| x < &100), 0);
If you want to insert an item to a sorted vector, while maintaining sort order:
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
let num = 42;
let idx = s.partition_point(|&x| x <= num);
s.insert(idx, num);
assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
Source ð¬This is a nightly-only experimental API. (substr_range
#126769)
Returns the index that an element reference points to.
Returns None
if element
does not point to the start of an element within the slice.
This method is useful for extending slice iterators like slice::split
.
Note that this uses pointer arithmetic and does not compare elements. To find the index of an element via comparison, use .iter().position()
instead.
Panics if T
is zero-sized.
Basic usage:
#![feature(substr_range)]
let nums: &[u32] = &[1, 7, 1, 1];
let num = &nums[2];
assert_eq!(num, &1);
assert_eq!(nums.element_offset(num), Some(2));
Returning None
with an unaligned element:
#![feature(substr_range)]
let arr: &[[u32; 2]] = &[[0, 1], [2, 3]];
let flat_arr: &[u32] = arr.as_flattened();
let ok_elm: &[u32; 2] = flat_arr[0..2].try_into().unwrap();
let weird_elm: &[u32; 2] = flat_arr[1..3].try_into().unwrap();
assert_eq!(ok_elm, &[0, 1]);
assert_eq!(weird_elm, &[1, 2]);
assert_eq!(arr.element_offset(ok_elm), Some(0)); assert_eq!(arr.element_offset(weird_elm), None);
Source ð¬This is a nightly-only experimental API. (substr_range
#126769)
Returns the range of indices that a subslice points to.
Returns None
if subslice
does not point within the slice or if it is not aligned with the elements in the slice.
This method does not compare elements. Instead, this method finds the location in the slice that subslice
was obtained from. To find the index of a subslice via comparison, instead use .windows()
.position()
.
This method is useful for extending slice iterators like slice::split
.
Note that this may return a false positive (either Some(0..0)
or Some(self.len()..self.len())
) if subslice
has a length of zero and points to the beginning or end of another, separate, slice.
Panics if T
is zero-sized.
Basic usage:
#![feature(substr_range)]
let nums = &[0, 5, 10, 0, 0, 5];
let mut iter = nums
.split(|t| *t == 0)
.map(|n| nums.subslice_range(n).unwrap());
assert_eq!(iter.next(), Some(0..0));
assert_eq!(iter.next(), Some(1..3));
assert_eq!(iter.next(), Some(4..4));
assert_eq!(iter.next(), Some(5..6));
1.79.0 · Source
Creates an iterator over the contiguous valid UTF-8 ranges of this slice, and the non-UTF-8 fragments in between.
See the Utf8Chunk
type for documentation of the items yielded by this iterator.
This function formats arbitrary but mostly-UTF-8 bytes into Rust source code in the form of a C-string literal (c"..."
).
use std::fmt::Write as _;
pub fn cstr_literal(bytes: &[u8]) -> String {
let mut repr = String::new();
repr.push_str("c\"");
for chunk in bytes.utf8_chunks() {
for ch in chunk.valid().chars() {
write!(repr, "{}", ch.escape_debug()).unwrap();
}
for byte in chunk.invalid() {
write!(repr, "\\x{:02X}", byte).unwrap();
}
}
repr.push('"');
repr
}
fn main() {
let lit = cstr_literal(b"\xferris the \xf0\x9f\xa6\x80\x07");
let expected = stringify!(c"\xFErris the ð¦\u{7}");
assert_eq!(lit, expected);
}
1.0.0 · Source
Copies self
into a new Vec
.
let s = [10, 40, 30];
let x = s.to_vec();
Source ð¬This is a nightly-only experimental API. (allocator_api
#32838)
Copies self
into a new Vec
with an allocator.
#![feature(allocator_api)]
use std::alloc::System;
let s = [10, 40, 30];
let x = s.to_vec_in(System);
1.40.0 · Source
Creates a vector by copying a slice n
times.
This function will panic if the capacity would overflow.
§Examplesassert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);
A panic upon overflow:
âb"0123456789abcdef".repeat(usize::MAX);
1.0.0 · Source
Flattens a slice of T
into a single value Self::Output
.
assert_eq!(["hello", "world"].concat(), "helloworld");
assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
1.3.0 · Source
Flattens a slice of T
into a single value Self::Output
, placing a given separator between each.
assert_eq!(["hello", "world"].join(" "), "hello world");
assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);
1.0.0 · Source
ðDeprecated since 1.3.0: renamed to join
Flattens a slice of T
into a single value Self::Output
, placing a given separator between each.
assert_eq!(["hello", "world"].connect(" "), "hello world");
assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
1.23.0 · Source
Returns a vector containing a copy of this slice where each byte is mapped to its ASCII upper case equivalent.
ASCII letters âaâ to âzâ are mapped to âAâ to âZâ, but non-ASCII letters are unchanged.
To uppercase the value in-place, use make_ascii_uppercase
.
Returns a vector containing a copy of this slice where each byte is mapped to its ASCII lower case equivalent.
ASCII letters âAâ to âZâ are mapped to âaâ to âzâ, but non-ASCII letters are unchanged.
To lowercase the value in-place, use make_ascii_lowercase
.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4