pub struct Bytes { /* private fields */ }
Expand description
A cheaply cloneable and sliceable chunk of contiguous memory.
Bytes
is an efficient container for storing and operating on contiguous
slices of memory. It is intended for use primarily in networking code, but
could have applications elsewhere as well.
Bytes
values facilitate zero-copy network programming by allowing multiple
Bytes
objects to point to the same underlying memory.
Bytes
does not have a single implementation. It is an interface, whose
exact behavior is implemented through dynamic dispatch in several underlying
implementations of Bytes
.
All Bytes
implementations must fulfill the following requirements:
- They are cheaply cloneable and thereby shareable between an unlimited amount of components, for example by modifying a reference count.
- Instances can be sliced to refer to a subset of the original buffer.
use bytes::Bytes;
let mut mem = Bytes::from("Hello world");
let a = mem.slice(0..5);
assert_eq!(a, "Hello");
let b = mem.split_to(6);
assert_eq!(mem, "world");
assert_eq!(b, "Hello ");
§Memory layout
The Bytes
struct itself is fairly small, limited to 4 usize
fields used
to track information about which segment of the underlying memory the
Bytes
handle has access to.
Bytes
keeps both a pointer to the shared state containing the full memory
slice and a pointer to the start of the region visible by the handle.
Bytes
also tracks the length of its view into the memory.
§Sharing
Bytes
contains a vtable, which allows implementations of Bytes
to define
how sharing/cloning is implemented in detail.
When Bytes::clone()
is called, Bytes
will call the vtable function for
cloning the backing storage in order to share it behind multiple Bytes
instances.
For Bytes
implementations which refer to constant memory (e.g. created
via Bytes::from_static()
) the cloning implementation will be a no-op.
For Bytes
implementations which point to a reference counted shared storage
(e.g. an Arc<[u8]>
), sharing will be implemented by increasing the
reference count.
Due to this mechanism, multiple Bytes
instances may point to the same
shared memory region.
Each Bytes
instance can point to different sections within that
memory region, and Bytes
instances may or may not have overlapping views
into the memory.
The following diagram visualizes a scenario where 2 Bytes
instances make
use of an Arc
-based backing storage, and provide access to different views:
Arc ptrs ┌─────────┐
________________________ / │ Bytes 2 │
/ └─────────┘
/ ┌───────────┐ | |
|_________/ │ Bytes 1 │ | |
| └───────────┘ | |
| | | ___/ data | tail
| data | tail |/ |
v v v v
┌─────┬─────┬───────────┬───────────────┬─────┐
│ Arc │ │ │ │ │
└─────┴─────┴───────────┴───────────────┴─────┘
Implementations§
Source§impl Bytes
impl Bytes
Sourcepub const fn new() -> Bytes
pub const fn new() -> Bytes
Creates a new empty Bytes
.
This will not allocate and the returned Bytes
handle will be empty.
§Examples
use bytes::Bytes;
let b = Bytes::new();
assert_eq!(&b[..], b"");
Sourcepub const fn from_static(bytes: &'static [u8]) -> Bytes
pub const fn from_static(bytes: &'static [u8]) -> Bytes
Creates a new Bytes
from a static slice.
The returned Bytes
will point directly to the static slice. There is
no allocating or copying.
§Examples
use bytes::Bytes;
let b = Bytes::from_static(b"hello");
assert_eq!(&b[..], b"hello");
Sourcepub const fn len(&self) -> usize
pub const fn len(&self) -> usize
Returns the number of bytes contained in this Bytes
.
§Examples
use bytes::Bytes;
let b = Bytes::from(&b"hello"[..]);
assert_eq!(b.len(), 5);
Sourcepub const fn is_empty(&self) -> bool
pub const fn is_empty(&self) -> bool
Returns true if the Bytes
has a length of 0.
§Examples
use bytes::Bytes;
let b = Bytes::new();
assert!(b.is_empty());
Sourcepub fn is_unique(&self) -> bool
pub fn is_unique(&self) -> bool
Returns true if this is the only reference to the data.
Always returns false if the data is backed by a static slice.
The result of this method may be invalidated immediately if another
thread clones this value while this is being called. Ensure you have
unique access to this value (&mut Bytes
) first if you need to be
certain the result is valid (i.e. for safety reasons)
§Examples
use bytes::Bytes;
let a = Bytes::from(vec![1, 2, 3]);
assert!(a.is_unique());
let b = a.clone();
assert!(!a.is_unique());
Sourcepub fn copy_from_slice(data: &[u8]) -> Bytes
pub fn copy_from_slice(data: &[u8]) -> Bytes
Creates Bytes
instance from slice, by copying it.
Sourcepub fn slice(&self, range: impl RangeBounds<usize>) -> Bytes
pub fn slice(&self, range: impl RangeBounds<usize>) -> Bytes
Returns a slice of self for the provided range.
This will increment the reference count for the underlying memory and
return a new Bytes
handle set to the slice.
This operation is O(1)
.
§Examples
use bytes::Bytes;
let a = Bytes::from(&b"hello world"[..]);
let b = a.slice(2..5);
assert_eq!(&b[..], b"llo");
§Panics
Requires that begin <= end
and end <= self.len()
, otherwise slicing
will panic.
Sourcepub fn slice_ref(&self, subset: &[u8]) -> Bytes
pub fn slice_ref(&self, subset: &[u8]) -> Bytes
Returns a slice of self that is equivalent to the given subset
.
When processing a Bytes
buffer with other tools, one often gets a
&[u8]
which is in fact a slice of the Bytes
, i.e. a subset of it.
This function turns that &[u8]
into another Bytes
, as if one had
called self.slice()
with the offsets that correspond to subset
.
This operation is O(1)
.
§Examples
use bytes::Bytes;
let bytes = Bytes::from(&b"012345678"[..]);
let as_slice = bytes.as_ref();
let subset = &as_slice[2..6];
let subslice = bytes.slice_ref(&subset);
assert_eq!(&subslice[..], b"2345");
§Panics
Requires that the given sub
slice is in fact contained within the
Bytes
buffer; otherwise this function will panic.
Sourcepub fn split_off(&mut self, at: usize) -> Bytes
pub fn split_off(&mut self, at: usize) -> Bytes
Splits the bytes into two at the given index.
Afterwards self
contains elements [0, at)
, and the returned Bytes
contains elements [at, len)
.
This is an O(1)
operation that just increases the reference count and
sets a few indices.
§Examples
use bytes::Bytes;
let mut a = Bytes::from(&b"hello world"[..]);
let b = a.split_off(5);
assert_eq!(&a[..], b"hello");
assert_eq!(&b[..], b" world");
§Panics
Panics if at > len
.
Sourcepub fn split_to(&mut self, at: usize) -> Bytes
pub fn split_to(&mut self, at: usize) -> Bytes
Splits the bytes into two at the given index.
Afterwards self
contains elements [at, len)
, and the returned
Bytes
contains elements [0, at)
.
This is an O(1)
operation that just increases the reference count and
sets a few indices.
§Examples
use bytes::Bytes;
let mut a = Bytes::from(&b"hello world"[..]);
let b = a.split_to(5);
assert_eq!(&a[..], b" world");
assert_eq!(&b[..], b"hello");
§Panics
Panics if at > len
.
Sourcepub fn truncate(&mut self, len: usize)
pub fn truncate(&mut self, len: usize)
Shortens the buffer, keeping the first len
bytes and dropping the
rest.
If len
is greater than the buffer’s current length, this has no
effect.
The split_off method can emulate truncate
, but this causes the
excess bytes to be returned instead of dropped.
§Examples
use bytes::Bytes;
let mut buf = Bytes::from(&b"hello world"[..]);
buf.truncate(5);
assert_eq!(buf, b"hello"[..]);
Methods from Deref<Target = [u8]>§
Sourcepub fn as_str(&self) -> &str
🔬This is a nightly-only experimental API. (ascii_char
)
pub fn as_str(&self) -> &str
ascii_char
)Views this slice of ASCII characters as a UTF-8 str
.
Sourcepub fn as_bytes(&self) -> &[u8] ⓘ
🔬This is a nightly-only experimental API. (ascii_char
)
pub fn as_bytes(&self) -> &[u8] ⓘ
ascii_char
)Views this slice of ASCII characters as a slice of u8
bytes.
1.23.0 · Sourcepub fn is_ascii(&self) -> bool
pub fn is_ascii(&self) -> bool
Checks if all bytes in this slice are within the ASCII range.
Sourcepub fn as_ascii(&self) -> Option<&[AsciiChar]>
🔬This is a nightly-only experimental API. (ascii_char
)
pub fn as_ascii(&self) -> Option<&[AsciiChar]>
ascii_char
)If this slice is_ascii
, returns it as a slice of
ASCII characters, otherwise returns None
.
Sourcepub unsafe fn as_ascii_unchecked(&self) -> &[AsciiChar]
🔬This is a nightly-only experimental API. (ascii_char
)
pub unsafe fn as_ascii_unchecked(&self) -> &[AsciiChar]
ascii_char
)Converts this slice of bytes into a slice of ASCII characters, without checking whether they’re valid.
§Safety
Every byte in the slice must be in 0..=127
, or else this is UB.
1.23.0 · Sourcepub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool
pub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool
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.
1.60.0 · Sourcepub fn escape_ascii(&self) -> EscapeAscii<'_>
pub fn escape_ascii(&self) -> EscapeAscii<'_>
Returns an iterator that produces an escaped version of this slice, treating it as an ASCII string.
§Examples
let 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 · Sourcepub fn trim_ascii_start(&self) -> &[u8] ⓘ
pub fn trim_ascii_start(&self) -> &[u8] ⓘ
Returns a byte slice with leading ASCII whitespace bytes removed.
‘Whitespace’ refers to the definition used by
u8::is_ascii_whitespace
.
§Examples
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 · Sourcepub fn trim_ascii_end(&self) -> &[u8] ⓘ
pub fn trim_ascii_end(&self) -> &[u8] ⓘ
Returns a byte slice with trailing ASCII whitespace bytes removed.
‘Whitespace’ refers to the definition used by
u8::is_ascii_whitespace
.
§Examples
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 · Sourcepub fn trim_ascii(&self) -> &[u8] ⓘ
pub fn trim_ascii(&self) -> &[u8] ⓘ
Returns a byte slice with leading and trailing ASCII whitespace bytes removed.
‘Whitespace’ refers to the definition used by
u8::is_ascii_whitespace
.
§Examples
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 · Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Returns true
if the slice has a length of 0.
§Examples
let a = [1, 2, 3];
assert!(!a.is_empty());
let b: &[i32] = &[];
assert!(b.is_empty());
1.0.0 · Sourcepub fn first(&self) -> Option<&T>
pub fn first(&self) -> Option<&T>
Returns the first element of the slice, or None
if it is empty.
§Examples
let v = [10, 40, 30];
assert_eq!(Some(&10), v.first());
let w: &[i32] = &[];
assert_eq!(None, w.first());
1.5.0 · Sourcepub fn split_first(&self) -> Option<(&T, &[T])>
pub fn split_first(&self) -> Option<(&T, &[T])>
Returns the first and all the rest of the elements of the slice, or None
if it is empty.
§Examples
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 · Sourcepub fn split_last(&self) -> Option<(&T, &[T])>
pub fn split_last(&self) -> Option<(&T, &[T])>
Returns the last and all the rest of the elements of the slice, or None
if it is empty.
§Examples
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 · Sourcepub fn last(&self) -> Option<&T>
pub fn last(&self) -> Option<&T>
Returns the last element of the slice, or None
if it is empty.
§Examples
let v = [10, 40, 30];
assert_eq!(Some(&30), v.last());
let w: &[i32] = &[];
assert_eq!(None, w.last());
1.77.0 · Sourcepub fn first_chunk<const N: usize>(&self) -> Option<&[T; N]>
pub fn first_chunk<const N: usize>(&self) -> Option<&[T; N]>
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
.
§Examples
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 · Sourcepub fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>
pub fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>
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
.
§Examples
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 · Sourcepub fn split_last_chunk<const N: usize>(&self) -> Option<(&[T], &[T; N])>
pub fn split_last_chunk<const N: usize>(&self) -> Option<(&[T], &[T; N])>
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
.
§Examples
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 · Sourcepub fn last_chunk<const N: usize>(&self) -> Option<&[T; N]>
pub fn last_chunk<const N: usize>(&self) -> Option<&[T; N]>
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
.
§Examples
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 · Sourcepub fn get<I>(&self, index: I) -> Option<&<I as SliceIndex<[T]>>::Output>where
I: SliceIndex<[T]>,
pub fn get<I>(&self, index: I) -> Option<&<I as SliceIndex<[T]>>::Output>where
I: SliceIndex<[T]>,
Returns a reference to an element or subslice depending on the type of index.
- If given a position, returns a reference to the element at that
position or
None
if out of bounds. - If given a range, returns the subslice corresponding to that range,
or
None
if out of bounds.
§Examples
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 · Sourcepub unsafe fn get_unchecked<I>(
&self,
index: I,
) -> &<I as SliceIndex<[T]>>::Outputwhere
I: SliceIndex<[T]>,
pub unsafe fn get_unchecked<I>(
&self,
index: I,
) -> &<I as SliceIndex<[T]>>::Outputwhere
I: SliceIndex<[T]>,
Returns a reference to an element or subslice, without doing bounds checking.
For a safe alternative see get
.
§Safety
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.
§Examples
let x = &[1, 2, 4];
unsafe {
assert_eq!(x.get_unchecked(1), &2);
}
1.0.0 · Sourcepub fn as_ptr(&self) -> *const T
pub fn as_ptr(&self) -> *const T
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.
§Examples
let 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 · Sourcepub fn as_ptr_range(&self) -> Range<*const T>
pub fn as_ptr_range(&self) -> Range<*const T>
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));
1.0.0 · Sourcepub fn iter(&self) -> Iter<'_, T>
pub fn iter(&self) -> Iter<'_, T>
Returns an iterator over the slice.
The iterator yields all items from start to end.
§Examples
let 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 · Sourcepub fn windows(&self, size: usize) -> Windows<'_, T>
pub fn windows(&self, size: usize) -> Windows<'_, T>
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
Panics if size
is 0.
§Examples
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());
There’s no windows_mut
, as that existing would let safe code violate the
“only one &mut
at a time to the same thing” rule. However, you can sometimes
use Cell::as_slice_of_cells
in
conjunction with windows
to accomplish something similar:
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 · Sourcepub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T>
pub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T>
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
Panics if chunk_size
is 0.
§Examples
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 · Sourcepub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T>
pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T>
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
Panics if chunk_size
is 0.
§Examples
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']);
Sourcepub unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]]
🔬This is a nightly-only experimental API. (slice_as_chunks
)
pub unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]]
slice_as_chunks
)Splits the slice into a slice of N
-element arrays,
assuming that there’s no remainder.
§Safety
This may only be called when
- The slice splits exactly into
N
-element chunks (akaself.len() % N == 0
). N != 0
.
§Examples
#![feature(slice_as_chunks)]
let slice: &[char] = &['l', 'o', 'r', 'e', 'm', '!'];
let chunks: &[[char; 1]] =
// SAFETY: 1-element chunks never have remainder
unsafe { slice.as_chunks_unchecked() };
assert_eq!(chunks, &[['l'], ['o'], ['r'], ['e'], ['m'], ['!']]);
let chunks: &[[char; 3]] =
// SAFETY: The slice length (6) is a multiple of 3
unsafe { slice.as_chunks_unchecked() };
assert_eq!(chunks, &[['l', 'o', 'r'], ['e', 'm', '!']]);
// These would be unsound:
// let chunks: &[[_; 5]] = slice.as_chunks_unchecked() // The slice length is not a multiple of 5
// let chunks: &[[_; 0]] = slice.as_chunks_unchecked() // Zero-length chunks are never allowed
Sourcepub fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T])
🔬This is a nightly-only experimental API. (slice_as_chunks
)
pub fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T])
slice_as_chunks
)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
.
§Panics
Panics if N
is 0. This check will most probably get changed to a compile time
error before this method gets stabilized.
§Examples
#![feature(slice_as_chunks)]
let 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:
#![feature(slice_as_chunks)]
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']]);
Sourcepub fn as_rchunks<const N: usize>(&self) -> (&[T], &[[T; N]])
🔬This is a nightly-only experimental API. (slice_as_chunks
)
pub fn as_rchunks<const N: usize>(&self) -> (&[T], &[[T; N]])
slice_as_chunks
)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
.
§Panics
Panics if N
is 0. This check will most probably get changed to a compile time
error before this method gets stabilized.
§Examples
#![feature(slice_as_chunks)]
let slice = ['l', 'o', 'r', 'e', 'm'];
let (remainder, chunks) = slice.as_rchunks();
assert_eq!(remainder, &['l']);
assert_eq!(chunks, &[['o', 'r'], ['e', 'm']]);
Sourcepub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N>
🔬This is a nightly-only experimental API. (array_chunks
)
pub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N>
array_chunks
)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
Panics if N
is 0. This check will most probably get changed to a compile time
error before this method gets stabilized.
§Examples
#![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']);
Sourcepub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N>
🔬This is a nightly-only experimental API. (array_windows
)
pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N>
array_windows
)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
Panics if N
is 0. This check will most probably get changed to a compile time
error before this method gets stabilized.
§Examples
#![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 · Sourcepub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T>
pub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T>
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
Panics if chunk_size
is 0.
§Examples
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 · Sourcepub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T>
pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T>
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
Panics if chunk_size
is 0.
§Examples
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 · Sourcepub fn chunk_by<F>(&self, pred: F) -> ChunkBy<'_, T, F>
pub fn chunk_by<F>(&self, pred: F) -> ChunkBy<'_, T, F>
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.
§Examples
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 · Sourcepub fn split_at(&self, mid: usize) -> (&[T], &[T])
pub fn split_at(&self, mid: usize) -> (&[T], &[T])
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
Panics if mid > len
. For a non-panicking alternative see
split_at_checked
.
§Examples
let v = [1, 2, 3, 4, 5, 6];
{
let (left, right) = v.split_at(0);
assert_eq!(left, []);
assert_eq!(right, [1, 2, 3, 4, 5, 6]);
}
{
let (left, right) = v.split_at(2);
assert_eq!(left, [1, 2]);
assert_eq!(right, [3, 4, 5, 6]);
}
{
let (left, right) = v.split_at(6);
assert_eq!(left, [1, 2, 3, 4, 5, 6]);
assert_eq!(right, []);
}
1.79.0 · Sourcepub unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T])
pub unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T])
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
.
§Safety
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()
.
§Examples
let v = [1, 2, 3, 4, 5, 6];
unsafe {
let (left, right) = v.split_at_unchecked(0);
assert_eq!(left, []);
assert_eq!(right, [1, 2, 3, 4, 5, 6]);
}
unsafe {
let (left, right) = v.split_at_unchecked(2);
assert_eq!(left, [1, 2]);
assert_eq!(right, [3, 4, 5, 6]);
}
unsafe {
let (left, right) = v.split_at_unchecked(6);
assert_eq!(left, [1, 2, 3, 4, 5, 6]);
assert_eq!(right, []);
}
1.80.0 · Sourcepub fn split_at_checked(&self, mid: usize) -> Option<(&[T], &[T])>
pub fn split_at_checked(&self, mid: usize) -> Option<(&[T], &[T])>
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
.
§Examples
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 · Sourcepub fn split<F>(&self, pred: F) -> Split<'_, T, F>
pub fn split<F>(&self, pred: F) -> Split<'_, T, F>
Returns an iterator over subslices separated by elements that match
pred
. The matched element is not contained in the subslices.
§Examples
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 · Sourcepub fn split_inclusive<F>(&self, pred: F) -> SplitInclusive<'_, T, F>
pub fn split_inclusive<F>(&self, pred: F) -> SplitInclusive<'_, T, F>
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.
§Examples
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 · Sourcepub fn rsplit<F>(&self, pred: F) -> RSplit<'_, T, F>
pub fn rsplit<F>(&self, pred: F) -> RSplit<'_, T, F>
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.
§Examples
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 · Sourcepub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<'_, T, F>
pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<'_, T, F>
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.
§Examples
Print 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 · Sourcepub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<'_, T, F>
pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<'_, T, F>
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.
§Examples
Print 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:?}");
}
Sourcepub fn split_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
🔬This is a nightly-only experimental API. (slice_split_once
)
pub fn split_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
slice_split_once
)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
.
§Examples
#![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);
Sourcepub fn rsplit_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
🔬This is a nightly-only experimental API. (slice_split_once
)
pub fn rsplit_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
slice_split_once
)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
.
§Examples
#![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 · Sourcepub fn contains(&self, x: &T) -> boolwhere
T: PartialEq,
pub fn contains(&self, x: &T) -> boolwhere
T: PartialEq,
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.
§Examples
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")]; // slice of `String`
assert!(v.iter().any(|e| e == "hello")); // search with `&str`
assert!(!v.iter().any(|e| e == "hi"));
1.0.0 · Sourcepub fn starts_with(&self, needle: &[T]) -> boolwhere
T: PartialEq,
pub fn starts_with(&self, needle: &[T]) -> boolwhere
T: PartialEq,
Returns true
if needle
is a prefix of the slice or equal to the slice.
§Examples
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 · Sourcepub fn ends_with(&self, needle: &[T]) -> boolwhere
T: PartialEq,
pub fn ends_with(&self, needle: &[T]) -> boolwhere
T: PartialEq,
Returns true
if needle
is a suffix of the slice or equal to the slice.
§Examples
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 · Sourcepub fn strip_prefix<P>(&self, prefix: &P) -> Option<&[T]>
pub fn strip_prefix<P>(&self, prefix: &P) -> Option<&[T]>
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
.
§Examples
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 · Sourcepub fn strip_suffix<P>(&self, suffix: &P) -> Option<&[T]>
pub fn strip_suffix<P>(&self, suffix: &P) -> Option<&[T]>
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
.
§Examples
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);
1.0.0 · Sourcepub fn binary_search(&self, x: &T) -> Result<usize, usize>where
T: Ord,
pub fn binary_search(&self, x: &T) -> Result<usize, usize>where
T: Ord,
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
.
§Examples
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));
// For something not found, the "range" of equal items is empty
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);
// If `num` is unique, `s.partition_point(|&x| x < num)` (with `<`) is equivalent to
// `s.binary_search(&num).unwrap_or_else(|x| x)`, but using `<=` will allow `insert`
// to shift less elements.
s.insert(idx, num);
assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
1.0.0 · Sourcepub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>
pub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>
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
.
§Examples
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 · Sourcepub fn binary_search_by_key<'a, B, F>(
&'a self,
b: &B,
f: F,
) -> Result<usize, usize>
pub fn binary_search_by_key<'a, B, F>( &'a self, b: &B, f: F, ) -> Result<usize, usize>
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
.
§Examples
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 · Sourcepub unsafe fn align_to<U>(&self) -> (&[T], &[U], &[T])
pub unsafe fn align_to<U>(&self) -> (&[T], &[U], &[T])
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.
§Safety
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.
§Examples
Basic usage:
unsafe {
let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
let (prefix, shorts, suffix) = bytes.align_to::<u16>();
// less_efficient_algorithm_for_bytes(prefix);
// more_efficient_algorithm_for_aligned_shorts(shorts);
// less_efficient_algorithm_for_bytes(suffix);
}
Sourcepub fn as_simd<const LANES: usize>(&self) -> (&[T], &[Simd<T, LANES>], &[T])
🔬This is a nightly-only experimental API. (portable_simd
)
pub fn as_simd<const LANES: usize>(&self) -> (&[T], &[Simd<T, LANES>], &[T])
portable_simd
)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.
§Panics
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
.
§Examples
#![feature(portable_simd)]
use core::simd::prelude::*;
let short = &[1, 2, 3];
let (prefix, middle, suffix) = short.as_simd::<4>();
assert_eq!(middle, []); // Not enough elements for anything in the middle
// They might be split in any possible way between prefix and suffix
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 · Sourcepub fn is_sorted(&self) -> boolwhere
T: PartialOrd,
pub fn is_sorted(&self) -> boolwhere
T: PartialOrd,
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.
§Examples
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 · Sourcepub fn is_sorted_by<'a, F>(&'a self, compare: F) -> bool
pub fn is_sorted_by<'a, F>(&'a self, compare: F) -> bool
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.
§Examples
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 · Sourcepub fn is_sorted_by_key<'a, F, K>(&'a self, f: F) -> bool
pub fn is_sorted_by_key<'a, F, K>(&'a self, f: F) -> bool
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.
§Examples
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 · Sourcepub fn partition_point<P>(&self, pred: P) -> usize
pub fn partition_point<P>(&self, pred: P) -> usize
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
.
§Examples
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]);
Sourcepub fn elem_offset(&self, element: &T) -> Option<usize>
🔬This is a nightly-only experimental API. (substr_range
)
pub fn elem_offset(&self, element: &T) -> Option<usize>
substr_range
)Returns the index that an element reference points to.
Returns None
if element
does not point within the slice or if it points between elements.
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
Panics if T
is zero-sized.
§Examples
Basic usage:
#![feature(substr_range)]
let nums: &[u32] = &[1, 7, 1, 1];
let num = &nums[2];
assert_eq!(num, &1);
assert_eq!(nums.elem_offset(num), Some(2));
Returning None
with an in-between 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.elem_offset(ok_elm), Some(0)); // Points to element 0
assert_eq!(arr.elem_offset(weird_elm), None); // Points between element 0 and 1
Sourcepub fn subslice_range(&self, subslice: &[T]) -> Option<Range<usize>>
🔬This is a nightly-only experimental API. (substr_range
)
pub fn subslice_range(&self, subslice: &[T]) -> Option<Range<usize>>
substr_range
)Returns the range of indices that a subslice points to.
Returns None
if subslice
does not point within the slice or if it points between elements.
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
Panics if T
is zero-sized.
§Examples
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.80.0 · Sourcepub fn as_flattened(&self) -> &[T]
pub fn as_flattened(&self) -> &[T]
Takes a &[[T; N]]
, and flattens it to a &[T]
.
§Panics
This panics if the length of the resulting slice would overflow a usize
.
This is only possible when flattening a slice of arrays of zero-sized
types, and thus tends to be irrelevant in practice. If
size_of::<T>() > 0
, this will never panic.
§Examples
assert_eq!([[1, 2, 3], [4, 5, 6]].as_flattened(), &[1, 2, 3, 4, 5, 6]);
assert_eq!(
[[1, 2, 3], [4, 5, 6]].as_flattened(),
[[1, 2], [3, 4], [5, 6]].as_flattened(),
);
let slice_of_empty_arrays: &[[i32; 0]] = &[[], [], [], [], []];
assert!(slice_of_empty_arrays.as_flattened().is_empty());
let empty_slice_of_arrays: &[[u32; 10]] = &[];
assert!(empty_slice_of_arrays.as_flattened().is_empty());
1.79.0 · Sourcepub fn utf8_chunks(&self) -> Utf8Chunks<'_>
pub fn utf8_chunks(&self) -> Utf8Chunks<'_>
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 documenation of the items yielded by this iterator.
§Examples
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() {
// Escapes \0, \t, \r, \n, \\, \', \", and uses \u{...} for non-printable characters.
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 · Sourcepub fn to_vec(&self) -> Vec<T>where
T: Clone,
pub fn to_vec(&self) -> Vec<T>where
T: Clone,
Copies self
into a new Vec
.
§Examples
let s = [10, 40, 30];
let x = s.to_vec();
// Here, `s` and `x` can be modified independently.
Sourcepub fn to_vec_in<A>(&self, alloc: A) -> Vec<T, A>
🔬This is a nightly-only experimental API. (allocator_api
)
pub fn to_vec_in<A>(&self, alloc: A) -> Vec<T, A>
allocator_api
)Copies self
into a new Vec
with an allocator.
§Examples
#![feature(allocator_api)]
use std::alloc::System;
let s = [10, 40, 30];
let x = s.to_vec_in(System);
// Here, `s` and `x` can be modified independently.
1.0.0 · Sourcepub fn concat<Item>(&self) -> <[T] as Concat<Item>>::Output ⓘ
pub fn concat<Item>(&self) -> <[T] as Concat<Item>>::Output ⓘ
Flattens a slice of T
into a single value Self::Output
.
§Examples
assert_eq!(["hello", "world"].concat(), "helloworld");
assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
1.3.0 · Sourcepub fn join<Separator>(
&self,
sep: Separator,
) -> <[T] as Join<Separator>>::Output ⓘ
pub fn join<Separator>( &self, sep: Separator, ) -> <[T] as Join<Separator>>::Output ⓘ
Flattens a slice of T
into a single value Self::Output
, placing a
given separator between each.
§Examples
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 · Sourcepub fn connect<Separator>(
&self,
sep: Separator,
) -> <[T] as Join<Separator>>::Output ⓘ
👎Deprecated since 1.3.0: renamed to join
pub fn connect<Separator>( &self, sep: Separator, ) -> <[T] as Join<Separator>>::Output ⓘ
Flattens a slice of T
into a single value Self::Output
, placing a
given separator between each.
§Examples
assert_eq!(["hello", "world"].connect(" "), "hello world");
assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
1.23.0 · Sourcepub fn to_ascii_uppercase(&self) -> Vec<u8>
pub fn to_ascii_uppercase(&self) -> Vec<u8>
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
.
1.23.0 · Sourcepub fn to_ascii_lowercase(&self) -> Vec<u8>
pub fn to_ascii_lowercase(&self) -> Vec<u8>
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
.
Trait Implementations§
Source§impl Buf for Bytes
impl Buf for Bytes
Source§fn remaining(&self) -> usize
fn remaining(&self) -> usize
Source§fn chunk(&self) -> &[u8] ⓘ
fn chunk(&self) -> &[u8] ⓘ
Buf::remaining()
. Note that this can return shorter slice (this allows
non-continuous internal representation). Read moreSource§fn copy_to_bytes(&mut self, len: usize) -> Bytes
fn copy_to_bytes(&mut self, len: usize) -> Bytes
Source§fn chunks_vectored<'a>(&'a self, dst: &mut [IoSlice<'a>]) -> usize
fn chunks_vectored<'a>(&'a self, dst: &mut [IoSlice<'a>]) -> usize
Source§fn has_remaining(&self) -> bool
fn has_remaining(&self) -> bool
Source§fn copy_to_slice(&mut self, dst: &mut [u8])
fn copy_to_slice(&mut self, dst: &mut [u8])
Source§fn get_u16(&mut self) -> u16
fn get_u16(&mut self) -> u16
self
in big-endian byte order. Read moreSource§fn get_u16_le(&mut self) -> u16
fn get_u16_le(&mut self) -> u16
self
in little-endian byte order. Read moreSource§fn get_u16_ne(&mut self) -> u16
fn get_u16_ne(&mut self) -> u16
self
in native-endian byte order. Read moreSource§fn get_i16(&mut self) -> i16
fn get_i16(&mut self) -> i16
self
in big-endian byte order. Read moreSource§fn get_i16_le(&mut self) -> i16
fn get_i16_le(&mut self) -> i16
self
in little-endian byte order. Read moreSource§fn get_i16_ne(&mut self) -> i16
fn get_i16_ne(&mut self) -> i16
self
in native-endian byte order. Read moreSource§fn get_u32(&mut self) -> u32
fn get_u32(&mut self) -> u32
self
in the big-endian byte order. Read moreSource§fn get_u32_le(&mut self) -> u32
fn get_u32_le(&mut self) -> u32
self
in the little-endian byte order. Read moreSource§fn get_u32_ne(&mut self) -> u32
fn get_u32_ne(&mut self) -> u32
self
in native-endian byte order. Read moreSource§fn get_i32(&mut self) -> i32
fn get_i32(&mut self) -> i32
self
in big-endian byte order. Read moreSource§fn get_i32_le(&mut self) -> i32
fn get_i32_le(&mut self) -> i32
self
in little-endian byte order. Read moreSource§fn get_i32_ne(&mut self) -> i32
fn get_i32_ne(&mut self) -> i32
self
in native-endian byte order. Read moreSource§fn get_u64(&mut self) -> u64
fn get_u64(&mut self) -> u64
self
in big-endian byte order. Read moreSource§fn get_u64_le(&mut self) -> u64
fn get_u64_le(&mut self) -> u64
self
in little-endian byte order. Read moreSource§fn get_u64_ne(&mut self) -> u64
fn get_u64_ne(&mut self) -> u64
self
in native-endian byte order. Read moreSource§fn get_i64(&mut self) -> i64
fn get_i64(&mut self) -> i64
self
in big-endian byte order. Read moreSource§fn get_i64_le(&mut self) -> i64
fn get_i64_le(&mut self) -> i64
self
in little-endian byte order. Read moreSource§fn get_i64_ne(&mut self) -> i64
fn get_i64_ne(&mut self) -> i64
self
in native-endian byte order. Read moreSource§fn get_u128(&mut self) -> u128
fn get_u128(&mut self) -> u128
self
in big-endian byte order. Read moreSource§fn get_u128_le(&mut self) -> u128
fn get_u128_le(&mut self) -> u128
self
in little-endian byte order. Read moreSource§fn get_u128_ne(&mut self) -> u128
fn get_u128_ne(&mut self) -> u128
self
in native-endian byte order. Read moreSource§fn get_i128(&mut self) -> i128
fn get_i128(&mut self) -> i128
self
in big-endian byte order. Read moreSource§fn get_i128_le(&mut self) -> i128
fn get_i128_le(&mut self) -> i128
self
in little-endian byte order. Read moreSource§fn get_i128_ne(&mut self) -> i128
fn get_i128_ne(&mut self) -> i128
self
in native-endian byte order. Read moreSource§fn get_uint(&mut self, nbytes: usize) -> u64
fn get_uint(&mut self, nbytes: usize) -> u64
self
in big-endian byte order. Read moreSource§fn get_uint_le(&mut self, nbytes: usize) -> u64
fn get_uint_le(&mut self, nbytes: usize) -> u64
self
in little-endian byte order. Read moreSource§fn get_uint_ne(&mut self, nbytes: usize) -> u64
fn get_uint_ne(&mut self, nbytes: usize) -> u64
self
in native-endian byte order. Read moreSource§fn get_int(&mut self, nbytes: usize) -> i64
fn get_int(&mut self, nbytes: usize) -> i64
self
in big-endian byte order. Read moreSource§fn get_int_le(&mut self, nbytes: usize) -> i64
fn get_int_le(&mut self, nbytes: usize) -> i64
self
in little-endian byte order. Read moreSource§fn get_int_ne(&mut self, nbytes: usize) -> i64
fn get_int_ne(&mut self, nbytes: usize) -> i64
self
in native-endian byte order. Read moreSource§fn get_f32(&mut self) -> f32
fn get_f32(&mut self) -> f32
self
in big-endian byte order. Read moreSource§fn get_f32_le(&mut self) -> f32
fn get_f32_le(&mut self) -> f32
self
in little-endian byte order. Read moreSource§fn get_f32_ne(&mut self) -> f32
fn get_f32_ne(&mut self) -> f32
self
in native-endian byte order. Read moreSource§fn get_f64(&mut self) -> f64
fn get_f64(&mut self) -> f64
self
in big-endian byte order. Read moreSource§fn get_f64_le(&mut self) -> f64
fn get_f64_le(&mut self) -> f64
self
in little-endian byte order. Read moreSource§fn get_f64_ne(&mut self) -> f64
fn get_f64_ne(&mut self) -> f64
self
in native-endian byte order. Read moreSource§impl FromIterator<u8> for Bytes
impl FromIterator<u8> for Bytes
Source§impl<'a> IntoIterator for &'a Bytes
impl<'a> IntoIterator for &'a Bytes
Source§impl IntoIterator for Bytes
impl IntoIterator for Bytes
Source§impl Ord for Bytes
impl Ord for Bytes
Source§impl<'a, T> PartialOrd<&'a T> for Bytes
impl<'a, T> PartialOrd<&'a T> for Bytes
Source§impl PartialOrd<[u8]> for Bytes
impl PartialOrd<[u8]> for Bytes
Source§impl PartialOrd<Bytes> for &[u8]
impl PartialOrd<Bytes> for &[u8]
Source§impl PartialOrd<Bytes> for &str
impl PartialOrd<Bytes> for &str
Source§impl PartialOrd<Bytes> for [u8]
impl PartialOrd<Bytes> for [u8]
Source§impl PartialOrd<Bytes> for str
impl PartialOrd<Bytes> for str
Source§impl PartialOrd<String> for Bytes
impl PartialOrd<String> for Bytes
Source§impl PartialOrd<Vec<u8>> for Bytes
impl PartialOrd<Vec<u8>> for Bytes
Source§impl PartialOrd<str> for Bytes
impl PartialOrd<str> for Bytes
Source§impl PartialOrd for Bytes
impl PartialOrd for Bytes
impl Eq for Bytes
impl Send for Bytes
impl Sync for Bytes
Auto Trait Implementations§
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)