Primitive Type slice1.0.0[−]
Expand description
一个动态大小的视图到一个连续的序列,[T]
。
这里的连续意味着元素的布局应使每个元素与其相邻元素之间的距离相同。
See also the std::slice
module.
切片是一个内存块的视图,表示为一个指针和一个长度。
// 切片 Vec
let vec = vec![1, 2, 3];
let int_slice = &vec[..];
// 将数组强制转换为切片
let str_slice: &[&str] = &["one", "two", "three"];
Run切片是可变的或共享的。
共享切片类型为 &[T]
,而可变切片类型为 &mut [T]
,其中 T
表示元素类型。
例如,您可以更改可变切片所指向的内存块:
let mut x = [1, 2, 3];
let x = &mut x[..]; // 取 `x` 的完整切片。
x[1] = 7;
assert_eq!(x, &[1, 7, 3]);
Run当切片存储所引用序列的长度时,它们的指针大小是 Sized
类型的两倍。
另请参见 动态大小的类型 上的引用。
let pointer_size = std::mem::size_of::<&u8>();
assert_eq!(2 * pointer_size, std::mem::size_of::<&[u8]>());
assert_eq!(2 * pointer_size, std::mem::size_of::<*const [u8]>());
assert_eq!(2 * pointer_size, std::mem::size_of::<Box<[u8]>>());
assert_eq!(2 * pointer_size, std::mem::size_of::<Rc<[u8]>>());
RunImplementations
pub 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]>,
pub fn get_mut<I>(
&mut self,
index: I
) -> Option<&mut <I as SliceIndex<[T]>>::Output> where
I: SliceIndex<[T]>,
pub fn get_mut<I>(
&mut self,
index: I
) -> Option<&mut <I as SliceIndex<[T]>>::Output> where
I: SliceIndex<[T]>,
pub unsafe fn get_unchecked<I>(
&self,
index: I
) -> &<I as SliceIndex<[T]>>::Output where
I: SliceIndex<[T]>,
pub unsafe fn get_unchecked<I>(
&self,
index: I
) -> &<I as SliceIndex<[T]>>::Output where
I: SliceIndex<[T]>,
返回对元素或子切片的引用,而不进行边界检查。
有关安全的选择,请参见 get
。
Safety
即使没有使用所得的引用,使用越界索引调用此方法也是 undefined behavior。
Examples
let x = &[1, 2, 4];
unsafe {
assert_eq!(x.get_unchecked(1), &2);
}
Runpub unsafe fn get_unchecked_mut<I>(
&mut self,
index: I
) -> &mut <I as SliceIndex<[T]>>::Output where
I: SliceIndex<[T]>,
pub unsafe fn get_unchecked_mut<I>(
&mut self,
index: I
) -> &mut <I as SliceIndex<[T]>>::Output where
I: SliceIndex<[T]>,
返回元素或子切片的可变引用,而不进行边界检查。
有关安全的选择,请参见 get_mut
。
Safety
即使没有使用所得的引用,使用越界索引调用此方法也是 undefined behavior。
Examples
let x = &mut [1, 2, 4];
unsafe {
let elem = x.get_unchecked_mut(1);
*elem = 13;
}
assert_eq!(x, &[1, 13, 4]);
Run将裸指针返回到切片的缓冲区。
调用者必须确保切片比该函数返回的指针有效,否则它将最终指向垃圾。
调用者还必须确保指针 (non-transitively) 所指向的内存 (从 UnsafeCell
内部除外) 永远不会使用此指针或从其派生的任何指针写入。
如果需要更改切片的内容,请使用 as_mut_ptr
。
修改此切片引用的容器可能会导致重新分配其缓冲区,这也将使指向它的任何指针无效。
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));
}
}
Run返回跨越切片的两个裸指针。
返回的范围是半开的,这意味着结束指针将 one 指向 切片的最后一个元素。 这样,一个空的切片由两个相等的指针表示,两个指针之间的差表示切片的大小。
有关使用这些指针的警告,请参见 as_ptr
。结束指针需要格外小心,因为它没有指向切片中的有效元素。
此函数对于与外部接口进行交互很有用,该外部接口使用两个指针来引用内存中的一系列元素,这在 C++ 中很常见。
检查指向元素的指针是否引用了此切片的元素,这也可能很有用:
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));
Run返回跨越切片的两个不安全的可变指针。
返回的范围是半开的,这意味着结束指针将 one 指向 切片的最后一个元素。 这样,一个空的切片由两个相等的指针表示,两个指针之间的差表示切片的大小。
有关使用这些指针的警告,请参见 as_mut_ptr
。
结束指针需要格外小心,因为它没有指向切片中的有效元素。
此函数对于与外部接口进行交互很有用,该外部接口使用两个指针来引用内存中的一系列元素,这在 C++ 中很常见。
在不做边界检查的情况下交换切片中的两个元素。
有关安全的替代方案,请参见 swap
。
Arguments
- a - 第一个元素的索引
- b - 第二个元素的索引
Safety
使用越界索引调用此方法是 未定义的行为。
调用者必须保证 a < self.len()
和 b < self.len()
。
Examples
#![feature(slice_swap_unchecked)]
let mut v = ["a", "b", "c", "d"];
// SAFETY: 我们知道 1 和 3 都是切片的索引
unsafe { v.swap_unchecked(1, 3) };
assert!(v == ["a", "d", "c", "b"]);
Run返回长度为 size
的所有连续 windows 上的迭代器。
windows 重叠。
如果切片短于 size
,则迭代器不返回任何值。
Panics
如果 size
为 0,就会出现 panics。
Examples
let slice = ['r', 'u', 's', 't'];
let mut iter = slice.windows(2);
assert_eq!(iter.next().unwrap(), &['r', 'u']);
assert_eq!(iter.next().unwrap(), &['u', 's']);
assert_eq!(iter.next().unwrap(), &['s', 't']);
assert!(iter.next().is_none());
Run如果切片短于 size
:
let slice = ['f', 'o', 'o'];
let mut iter = slice.windows(4);
assert!(iter.next().is_none());
Run从切片的开头开始,一次返回对切片的 chunk_size
元素的迭代器。
块是切片,并且不重叠。如果 chunk_size
不划分切片的长度,则最后一块的长度将不为 chunk_size
。
有关此迭代器的变体的信息,请参见 chunks_exact
,它返回始终完全由 chunk_size
元素组成的块; 对于相同迭代器,请参见 rchunks
,但均从切片的末尾开始。
Panics
如果 chunk_size
为 0,就会出现 panics。
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());
Runpub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T>ⓘNotable traits for ChunksMut<'a, T>impl<'a, T> Iterator for ChunksMut<'a, T> type Item = &'a mut [T];
pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T>ⓘNotable traits for ChunksMut<'a, T>impl<'a, T> Iterator for ChunksMut<'a, T> type Item = &'a mut [T];
impl<'a, T> Iterator for ChunksMut<'a, T> type Item = &'a mut [T];
从切片的开头开始,一次返回对切片的 chunk_size
元素的迭代器。
块是可变切片,并且不重叠。如果 chunk_size
不划分切片的长度,则最后一块的长度将不为 chunk_size
。
有关此迭代器的变体的信息,请参见 chunks_exact_mut
,该变体返回始终完全相同的 chunk_size
元素的块; 对于相同的迭代器,请参见 rchunks_mut
,但均从切片的末尾开始。
Panics
如果 chunk_size
为 0,就会出现 panics。
Examples
let v = &mut [0, 0, 0, 0, 0];
let mut count = 1;
for chunk in v.chunks_mut(2) {
for elem in chunk.iter_mut() {
*elem += count;
}
count += 1;
}
assert_eq!(v, &[1, 1, 2, 2, 3]);
Run1.31.0[src]pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T>ⓘNotable traits for ChunksExact<'a, T>impl<'a, T> Iterator for ChunksExact<'a, T> type Item = &'a [T];
pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T>ⓘNotable traits for ChunksExact<'a, T>impl<'a, T> Iterator for ChunksExact<'a, T> type Item = &'a [T];
impl<'a, T> Iterator for ChunksExact<'a, T> type Item = &'a [T];
从切片的开头开始,一次返回对切片的 chunk_size
元素的迭代器。
块是切片,并且不重叠。
如果 chunk_size
不划分切片的长度,则最后 chunk_size-1
个元素将被省略,并可从迭代器的 remainder
函数中检索。
由于每个块都具有完全 chunk_size
元素,因此与 chunks
相比,编译器通常可以更好地优化结果代码。
请参见 chunks
以获取此迭代器的变体,该变体还以较小的块的形式返回其余部分,并以 rchunks_exact
获取相同的迭代器,但从切片的末尾开始。
Panics
如果 chunk_size
为 0,就会出现 panics。
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']);
Run1.31.0[src]pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T>ⓘNotable traits for ChunksExactMut<'a, T>impl<'a, T> Iterator for ChunksExactMut<'a, T> type Item = &'a mut [T];
pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T>ⓘNotable traits for ChunksExactMut<'a, T>impl<'a, T> Iterator for ChunksExactMut<'a, T> type Item = &'a mut [T];
impl<'a, T> Iterator for ChunksExactMut<'a, T> type Item = &'a mut [T];
从切片的开头开始,一次返回对切片的 chunk_size
元素的迭代器。
块是可变切片,并且不重叠。
如果 chunk_size
不划分切片的长度,则最后 chunk_size-1
个元素将被省略,并可从迭代器的 into_remainder
函数中检索。
由于每个块都具有完全 chunk_size
元素,因此与 chunks_mut
相比,编译器通常可以更好地优化结果代码。
请参见 chunks_mut
以获取此迭代器的变体,该变体还以较小的块的形式返回其余部分,并以 rchunks_exact_mut
获取相同的迭代器,但从切片的末尾开始。
Panics
如果 chunk_size
为 0,就会出现 panics。
Examples
let v = &mut [0, 0, 0, 0, 0];
let mut count = 1;
for chunk in v.chunks_exact_mut(2) {
for elem in chunk.iter_mut() {
*elem += count;
}
count += 1;
}
assert_eq!(v, &[1, 1, 2, 2, 0]);
Run假设没有余数,将切片拆分为 N 个元素数组的切片。
Safety
只能在以下情况下调用
- 切片精确地分为
N
个元素块 (也称为self.len() % N == 0
)。 N != 0
.
Examples
#![feature(slice_as_chunks)]
let slice: &[char] = &['l', 'o', 'r', 'e', 'm', '!'];
let chunks: &[[char; 1]] =
// SAFETY: 1 个元素的块永远不会剩余
unsafe { slice.as_chunks_unchecked() };
assert_eq!(chunks, &[['l'], ['o'], ['r'], ['e'], ['m'], ['!']]);
let chunks: &[[char; 3]] =
// SAFETY: 切片长度 (6) 是 3 的倍数
unsafe { slice.as_chunks_unchecked() };
assert_eq!(chunks, &[['l', 'o', 'r'], ['e', 'm', '!']]);
// 这些是不健全的:
// `let chunks: &[[_; 5]] = slice.as_chunks_unchecked()` // 切片长度不是 5 个的倍数: `let chunks: &[[_; 0]] = slice.as_chunks_unchecked()` // 永远不允许零长度的块
Run从切片的开头开始,将切片分成 N
个元素数组的切片,然后将其长度严格小于 N
的其余切片切成薄片。
Panics
如果 N
为 0,就会出现 panics。在此方法稳定之前,此检查很可能会更改为编译时错误。
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']);
Run从切片的末尾开始,将切片分成 N
个元素数组的切片,然后将其长度严格小于 N
的其余切片切成薄片。
Panics
如果 N
为 0,就会出现 panics。在此方法稳定之前,此检查很可能会更改为编译时错误。
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']]);
Runpub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N>ⓘNotable traits for ArrayChunks<'a, T, N>impl<'a, T, const N: usize> Iterator for ArrayChunks<'a, T, N> type Item = &'a [T; N];
pub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N>ⓘNotable traits for ArrayChunks<'a, T, N>impl<'a, T, const N: usize> Iterator for ArrayChunks<'a, T, N> type Item = &'a [T; N];
impl<'a, T, const N: usize> Iterator for ArrayChunks<'a, T, N> type Item = &'a [T; N];
从切片的开头开始,一次返回对切片的 N
元素的迭代器。
这些块是数组引用,并且不重叠。
如果 N
不划分切片的长度,则最后 N-1
个元素将被省略,并可从迭代器的 remainder
函数中检索。
此方法与 chunks_exact
等效为 const 泛型。
Panics
如果 N
为 0,就会出现 panics。在此方法稳定之前,此检查很可能会更改为编译时错误。
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']);
Run假设没有余数,将切片拆分为 N 个元素数组的切片。
Safety
只能在以下情况下调用
- 切片精确地分为
N
个元素块 (也称为self.len() % N == 0
)。 N != 0
.
Examples
#![feature(slice_as_chunks)]
let slice: &mut [char] = &mut ['l', 'o', 'r', 'e', 'm', '!'];
let chunks: &mut [[char; 1]] =
// SAFETY: 1 个元素的块永远不会剩余
unsafe { slice.as_chunks_unchecked_mut() };
chunks[0] = ['L'];
assert_eq!(chunks, &[['L'], ['o'], ['r'], ['e'], ['m'], ['!']]);
let chunks: &mut [[char; 3]] =
// SAFETY: 切片长度 (6) 是 3 的倍数
unsafe { slice.as_chunks_unchecked_mut() };
chunks[1] = ['a', 'x', '?'];
assert_eq!(slice, &['L', 'o', 'r', 'a', 'x', '?']);
// 这些是不健全的:
// `let chunks: &[[_; 5]] = slice.as_chunks_unchecked_mut()` // 切片长度不是 5 的倍数: `let chunks: &[[_; 0]] = slice.as_chunks_unchecked_mut()` // 永远不允许零长度的块
Run从切片的开头开始,将切片分成 N
个元素数组的切片,然后将其长度严格小于 N
的其余切片切成薄片。
Panics
如果 N
为 0,就会出现 panics。在此方法稳定之前,此检查很可能会更改为编译时错误。
Examples
#![feature(slice_as_chunks)]
let v = &mut [0, 0, 0, 0, 0];
let mut count = 1;
let (chunks, remainder) = v.as_chunks_mut();
remainder[0] = 9;
for chunk in chunks {
*chunk = [count; 2];
count += 1;
}
assert_eq!(v, &[1, 1, 2, 2, 9]);
Run从切片的末尾开始,将切片分成 N
个元素数组的切片,然后将其长度严格小于 N
的其余切片切成薄片。
Panics
如果 N
为 0,就会出现 panics。在此方法稳定之前,此检查很可能会更改为编译时错误。
Examples
#![feature(slice_as_chunks)]
let v = &mut [0, 0, 0, 0, 0];
let mut count = 1;
let (remainder, chunks) = v.as_rchunks_mut();
remainder[0] = 9;
for chunk in chunks {
*chunk = [count; 2];
count += 1;
}
assert_eq!(v, &[9, 1, 1, 2, 2]);
Runpub fn array_chunks_mut<const N: usize>(&mut self) -> ArrayChunksMut<'_, T, N>ⓘNotable traits for ArrayChunksMut<'a, T, N>impl<'a, T, const N: usize> Iterator for ArrayChunksMut<'a, T, N> type Item = &'a mut [T; N];
pub fn array_chunks_mut<const N: usize>(&mut self) -> ArrayChunksMut<'_, T, N>ⓘNotable traits for ArrayChunksMut<'a, T, N>impl<'a, T, const N: usize> Iterator for ArrayChunksMut<'a, T, N> type Item = &'a mut [T; N];
impl<'a, T, const N: usize> Iterator for ArrayChunksMut<'a, T, N> type Item = &'a mut [T; N];
从切片的开头开始,一次返回对切片的 N
元素的迭代器。
这些块是可变数组引用,并且不重叠。
如果 N
不划分切片的长度,则最后 N-1
个元素将被省略,并可从迭代器的 into_remainder
函数中检索。
此方法与 chunks_exact_mut
等效为 const 泛型。
Panics
如果 N
为 0,就会出现 panics。在此方法稳定之前,此检查很可能会更改为编译时错误。
Examples
#![feature(array_chunks)]
let v = &mut [0, 0, 0, 0, 0];
let mut count = 1;
for chunk in v.array_chunks_mut() {
*chunk = [count; 2];
count += 1;
}
assert_eq!(v, &[1, 1, 2, 2, 0]);
Runpub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N>ⓘNotable traits for ArrayWindows<'a, T, N>impl<'a, T, const N: usize> Iterator for ArrayWindows<'a, T, N> type Item = &'a [T; N];
pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N>ⓘNotable traits for ArrayWindows<'a, T, N>impl<'a, T, const N: usize> Iterator for ArrayWindows<'a, T, N> type Item = &'a [T; N];
impl<'a, T, const N: usize> Iterator for ArrayWindows<'a, T, N> type Item = &'a [T; N];
从切片的开头开始,在切片的 N
元素的重叠 windows 上返回迭代器。
这是 windows
的 const 泛型等效项。
如果 N
大于切片的大小,则不会返回 windows。
Panics
如果 N
为 0,就会出现 panics。
在此方法稳定之前,此检查很可能会更改为编译时错误。
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());
Run从切片的末尾开始,一次返回对切片的 chunk_size
元素的迭代器。
块是切片,并且不重叠。如果 chunk_size
不划分切片的长度,则最后一块的长度将不为 chunk_size
。
有关此迭代器的变体的信息,请参见 rchunks_exact
,该变体返回始终完全相同的 chunk_size
元素的块; 对于相同的迭代器,请参见 chunks
,但从切片的开头开始。
Panics
如果 chunk_size
为 0,就会出现 panics。
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());
Run1.31.0[src]pub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T>ⓘNotable traits for RChunksMut<'a, T>impl<'a, T> Iterator for RChunksMut<'a, T> type Item = &'a mut [T];
pub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T>ⓘNotable traits for RChunksMut<'a, T>impl<'a, T> Iterator for RChunksMut<'a, T> type Item = &'a mut [T];
impl<'a, T> Iterator for RChunksMut<'a, T> type Item = &'a mut [T];
从切片的末尾开始,一次返回对切片的 chunk_size
元素的迭代器。
块是可变切片,并且不重叠。如果 chunk_size
不划分切片的长度,则最后一块的长度将不为 chunk_size
。
有关此迭代器的变体的信息,请参见 rchunks_exact_mut
,该变体返回始终完全相同的 chunk_size
元素的块; 对于相同的迭代器,请参见 chunks_mut
,但从切片的开头开始。
Panics
如果 chunk_size
为 0,就会出现 panics。
Examples
let v = &mut [0, 0, 0, 0, 0];
let mut count = 1;
for chunk in v.rchunks_mut(2) {
for elem in chunk.iter_mut() {
*elem += count;
}
count += 1;
}
assert_eq!(v, &[3, 2, 2, 1, 1]);
Run1.31.0[src]pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T>ⓘNotable traits for RChunksExact<'a, T>impl<'a, T> Iterator for RChunksExact<'a, T> type Item = &'a [T];
pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T>ⓘNotable traits for RChunksExact<'a, T>impl<'a, T> Iterator for RChunksExact<'a, T> type Item = &'a [T];
impl<'a, T> Iterator for RChunksExact<'a, T> type Item = &'a [T];
从切片的末尾开始,一次返回对切片的 chunk_size
元素的迭代器。
块是切片,并且不重叠。
如果 chunk_size
不划分切片的长度,则最后 chunk_size-1
个元素将被省略,并可从迭代器的 remainder
函数中检索。
由于每个块都具有完全 chunk_size
元素,因此与 chunks
相比,编译器通常可以更好地优化结果代码。
请参见 rchunks
以获取此迭代器的变体,该变体还以较小的块的形式返回其余部分,并以 chunks_exact
获取相同的迭代器,但从切片的开头开始。
Panics
如果 chunk_size
为 0,就会出现 panics。
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']);
Run1.31.0[src]pub fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T>ⓘNotable traits for RChunksExactMut<'a, T>impl<'a, T> Iterator for RChunksExactMut<'a, T> type Item = &'a mut [T];
pub fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T>ⓘNotable traits for RChunksExactMut<'a, T>impl<'a, T> Iterator for RChunksExactMut<'a, T> type Item = &'a mut [T];
impl<'a, T> Iterator for RChunksExactMut<'a, T> type Item = &'a mut [T];
从切片的末尾开始,一次返回对切片的 chunk_size
元素的迭代器。
块是可变切片,并且不重叠。
如果 chunk_size
不划分切片的长度,则最后 chunk_size-1
个元素将被省略,并可从迭代器的 into_remainder
函数中检索。
由于每个块都具有完全 chunk_size
元素,因此与 chunks_mut
相比,编译器通常可以更好地优化结果代码。
请参见 rchunks_mut
以获取此迭代器的变体,该变体还以较小的块的形式返回其余部分,并以 chunks_exact_mut
获取相同的迭代器,但从切片的开头开始。
Panics
如果 chunk_size
为 0,就会出现 panics。
Examples
let v = &mut [0, 0, 0, 0, 0];
let mut count = 1;
for chunk in v.rchunks_exact_mut(2) {
for elem in chunk.iter_mut() {
*elem += count;
}
count += 1;
}
assert_eq!(v, &[0, 2, 2, 1, 1]);
Run返回在切片上使用迭代器生成迭代器的迭代器,这些谓词使用谓词将它们分隔开。
谓词在紧随其后的两个元素上调用,这意味着谓词在 slice[0]
和 slice[1]
上调用,然后在 slice[1]
和 slice[2]
上调用,依此类推。
Examples
#![feature(slice_group_by)]
let slice = &[1, 1, 1, 3, 3, 2, 2, 2];
let mut iter = slice.group_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);
Run此方法可用于提取排序的子切片:
#![feature(slice_group_by)]
let slice = &[1, 1, 2, 3, 2, 3, 2, 3, 4];
let mut iter = slice.group_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);
Runpub fn group_by_mut<F>(&mut self, pred: F) -> GroupByMut<'_, T, F>ⓘNotable traits for GroupByMut<'a, T, P>impl<'a, T, P> Iterator for GroupByMut<'a, T, P> where
T: 'a,
P: FnMut(&T, &T) -> bool, type Item = &'a mut [T];
where
F: FnMut(&T, &T) -> bool,
pub fn group_by_mut<F>(&mut self, pred: F) -> GroupByMut<'_, T, F>ⓘNotable traits for GroupByMut<'a, T, P>impl<'a, T, P> Iterator for GroupByMut<'a, T, P> where
T: 'a,
P: FnMut(&T, &T) -> bool, type Item = &'a mut [T];
where
F: FnMut(&T, &T) -> bool,
impl<'a, T, P> Iterator for GroupByMut<'a, T, P> where
T: 'a,
P: FnMut(&T, &T) -> bool, type Item = &'a mut [T];
返回在切片上使用谓词将其分离的迭代器,以生成不重叠的可变元素游程。
谓词在紧随其后的两个元素上调用,这意味着谓词在 slice[0]
和 slice[1]
上调用,然后在 slice[1]
和 slice[2]
上调用,依此类推。
Examples
#![feature(slice_group_by)]
let slice = &mut [1, 1, 1, 3, 3, 2, 2, 2];
let mut iter = slice.group_by_mut(|a, b| a == b);
assert_eq!(iter.next(), Some(&mut [1, 1, 1][..]));
assert_eq!(iter.next(), Some(&mut [3, 3][..]));
assert_eq!(iter.next(), Some(&mut [2, 2, 2][..]));
assert_eq!(iter.next(), None);
Run此方法可用于提取排序的子切片:
#![feature(slice_group_by)]
let slice = &mut [1, 1, 2, 3, 2, 3, 2, 3, 4];
let mut iter = slice.group_by_mut(|a, b| a <= b);
assert_eq!(iter.next(), Some(&mut [1, 1, 2, 3][..]));
assert_eq!(iter.next(), Some(&mut [2, 3][..]));
assert_eq!(iter.next(), Some(&mut [2, 3, 4][..]));
assert_eq!(iter.next(), None);
Run在索引处将一个切片分为两个。
第一个将包含 [0, mid)
的所有索引 (不包括索引 mid
本身),第二个将包含 [mid, len)
的所有索引 (不包括索引 len
本身)。
Panics
如果为 mid > len
,就会出现 panics。
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, []);
}
Run在索引处将一个可变切片分成两个。
第一个将包含 [0, mid)
的所有索引 (不包括索引 mid
本身),第二个将包含 [mid, len)
的所有索引 (不包括索引 len
本身)。
Panics
如果为 mid > len
,就会出现 panics。
Examples
let mut v = [1, 0, 3, 0, 5, 6];
let (left, right) = v.split_at_mut(2);
assert_eq!(left, [1, 0]);
assert_eq!(right, [3, 0, 5, 6]);
left[1] = 2;
right[1] = 4;
assert_eq!(v, [1, 2, 3, 4, 5, 6]);
Run在索引处将一个切片分为两个,而无需进行边界检查。
第一个将包含 [0, mid)
的所有索引 (不包括索引 mid
本身),第二个将包含 [mid, len)
的所有索引 (不包括索引 len
本身)。
有关安全的选择,请参见 split_at
。
Safety
即使没有使用所得的引用,使用越界索引调用此方法也是 undefined behavior。调用者必须确保 0 <= mid <= self.len()
.
Examples
#![feature(slice_split_at_unchecked)]
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, []);
}
Run在索引处将一个可变切片分为两个,而无需进行边界检查。
第一个将包含 [0, mid)
的所有索引 (不包括索引 mid
本身),第二个将包含 [mid, len)
的所有索引 (不包括索引 len
本身)。
有关安全的选择,请参见 split_at_mut
。
Safety
即使没有使用所得的引用,使用越界索引调用此方法也是 undefined behavior。调用者必须确保 0 <= mid <= self.len()
.
Examples
#![feature(slice_split_at_unchecked)]
let mut v = [1, 0, 3, 0, 5, 6];
// 限制借用的生命周期
unsafe {
let (left, right) = v.split_at_mut_unchecked(2);
assert_eq!(left, [1, 0]);
assert_eq!(right, [3, 0, 5, 6]);
left[1] = 2;
right[1] = 4;
}
assert_eq!(v, [1, 2, 3, 4, 5, 6]);
Run将一个切片分成一个数组和一个索引处的剩余切片。
该数组将包含来自 [0, N)
的所有索引 (不包括索引 N
本身),并且切片将包含来自 [N, len)
的所有索引 (不包括索引 len
本身)。
Panics
如果 N > len
,就会出现 panics。
Examples
#![feature(split_array)]
let v = &[1, 2, 3, 4, 5, 6][..];
{
let (left, right) = v.split_array_ref::<0>();
assert_eq!(left, &[]);
assert_eq!(right, [1, 2, 3, 4, 5, 6]);
}
{
let (left, right) = v.split_array_ref::<2>();
assert_eq!(left, &[1, 2]);
assert_eq!(right, [3, 4, 5, 6]);
}
{
let (left, right) = v.split_array_ref::<6>();
assert_eq!(left, &[1, 2, 3, 4, 5, 6]);
assert_eq!(right, []);
}
Run将一个可变切片分成一个数组和一个索引处的剩余切片。
该数组将包含来自 [0, N)
的所有索引 (不包括索引 N
本身),并且切片将包含来自 [N, len)
的所有索引 (不包括索引 len
本身)。
Panics
如果 N > len
,就会出现 panics。
Examples
#![feature(split_array)]
let mut v = &mut [1, 0, 3, 0, 5, 6][..];
let (left, right) = v.split_array_mut::<2>();
assert_eq!(left, &mut [1, 0]);
assert_eq!(right, [3, 0, 5, 6]);
left[1] = 2;
right[1] = 4;
assert_eq!(v, [1, 2, 3, 4, 5, 6]);
Run将一个切片分成一个数组和一个从末尾开始的索引处的剩余切片。
该切片将包含来自 [0, len - N)
的所有索引 (不包括索引 len - N
本身),而数组将包含来自 [len - N, len)
的所有索引 (不包括索引 len
本身)。
Panics
如果 N > len
,就会出现 panics。
Examples
#![feature(split_array)]
let v = &[1, 2, 3, 4, 5, 6][..];
{
let (left, right) = v.rsplit_array_ref::<0>();
assert_eq!(left, [1, 2, 3, 4, 5, 6]);
assert_eq!(right, &[]);
}
{
let (left, right) = v.rsplit_array_ref::<2>();
assert_eq!(left, [1, 2, 3, 4]);
assert_eq!(right, &[5, 6]);
}
{
let (left, right) = v.rsplit_array_ref::<6>();
assert_eq!(left, []);
assert_eq!(right, &[1, 2, 3, 4, 5, 6]);
}
Run将一个可变切片分成一个数组和一个从末尾开始的索引处的剩余切片。
该切片将包含来自 [0, len - N)
的所有索引 (不包括索引 N
本身),而数组将包含来自 [len - N, len)
的所有索引 (不包括索引 len
本身)。
Panics
如果 N > len
,就会出现 panics。
Examples
#![feature(split_array)]
let mut v = &mut [1, 0, 3, 0, 5, 6][..];
let (left, right) = v.rsplit_array_mut::<4>();
assert_eq!(left, [1, 0]);
assert_eq!(right, &mut [3, 0, 5, 6]);
left[1] = 2;
right[1] = 4;
assert_eq!(v, [1, 2, 3, 4, 5, 6]);
Run返回由与 pred
匹配的元素分隔的子切片上的迭代器。
匹配的元素不包含在子切片中。
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());
Run如果第一个元素匹配,则空切片将是迭代器返回的第一个项。 同样,如果切片中的最后一个元素匹配,则空切片将是迭代器返回的最后一个项:
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());
Run如果两个匹配的元素直接相邻,则它们之间将出现一个空的切片:
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());
Run1.51.0[src]pub fn split_inclusive<F>(&self, pred: F) -> SplitInclusive<'_, T, F>ⓘNotable traits for SplitInclusive<'a, T, P>impl<'a, T, P> Iterator for SplitInclusive<'a, T, P> where
P: FnMut(&T) -> bool, type Item = &'a [T];
where
F: FnMut(&T) -> bool,
pub fn split_inclusive<F>(&self, pred: F) -> SplitInclusive<'_, T, F>ⓘNotable traits for SplitInclusive<'a, T, P>impl<'a, T, P> Iterator for SplitInclusive<'a, T, P> where
P: FnMut(&T) -> bool, type Item = &'a [T];
where
F: FnMut(&T) -> bool,
impl<'a, T, P> Iterator for SplitInclusive<'a, T, P> where
P: FnMut(&T) -> bool, type Item = &'a [T];
返回由与 pred
匹配的元素分隔的子切片上的迭代器。
匹配的元素包含在上一个子切片的末尾作为终止符。
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());
Run如果切片的最后一个元素匹配,则该元素将被视为前一个切片的终止符。
该切片将是迭代器返回的最后一个项目。
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());
Run1.51.0[src]pub fn split_inclusive_mut<F>(&mut self, pred: F) -> SplitInclusiveMut<'_, T, F>ⓘNotable traits for SplitInclusiveMut<'a, T, P>impl<'a, T, P> Iterator for SplitInclusiveMut<'a, T, P> where
P: FnMut(&T) -> bool, type Item = &'a mut [T];
where
F: FnMut(&T) -> bool,
pub fn split_inclusive_mut<F>(&mut self, pred: F) -> SplitInclusiveMut<'_, T, F>ⓘNotable traits for SplitInclusiveMut<'a, T, P>impl<'a, T, P> Iterator for SplitInclusiveMut<'a, T, P> where
P: FnMut(&T) -> bool, type Item = &'a mut [T];
where
F: FnMut(&T) -> bool,
impl<'a, T, P> Iterator for SplitInclusiveMut<'a, T, P> where
P: FnMut(&T) -> bool, type Item = &'a mut [T];
在子切片上返回一个迭代器,该迭代器由与 pred
匹配的元素分隔,从切片的末尾开始并向后工作。
匹配的元素不包含在子切片中。
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);
Run与 split()
一样,如果第一个或最后一个元素匹配,则空切片将是迭代器返回的第一个 (或最后一个) 项。
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);
Runpub fn rsplitn_mut<F>(&mut self, n: usize, pred: F) -> RSplitNMut<'_, T, F>ⓘNotable traits for RSplitNMut<'a, T, P>impl<'a, T, P> Iterator for RSplitNMut<'a, T, P> where
P: FnMut(&T) -> bool, type Item = &'a mut [T];
where
F: FnMut(&T) -> bool,
pub fn rsplitn_mut<F>(&mut self, n: usize, pred: F) -> RSplitNMut<'_, T, F>ⓘNotable traits for RSplitNMut<'a, T, P>impl<'a, T, P> Iterator for RSplitNMut<'a, T, P> where
P: FnMut(&T) -> bool, type Item = &'a mut [T];
where
F: FnMut(&T) -> bool,
impl<'a, T, P> Iterator for RSplitNMut<'a, T, P> where
P: FnMut(&T) -> bool, type Item = &'a mut [T];
如果切片包含具有给定值的元素,则返回 true
。
Examples
let v = [10, 40, 30];
assert!(v.contains(&30));
assert!(!v.contains(&50));
Run如果您没有 &T
,但有其他一些可以与之比较的值 (例如,String
实现 PartialEq<str>
),则可以使用 iter().any
:
let v = [String::from("hello"), String::from("world")]; // `String` 切片
assert!(v.iter().any(|e| e == "hello")); // 用 `&str` 搜索
assert!(!v.iter().any(|e| e == "hi"));
Run如果 needle
是切片的前缀,则返回 true
。
Examples
let v = [10, 40, 30];
assert!(v.starts_with(&[10]));
assert!(v.starts_with(&[10, 40]));
assert!(!v.starts_with(&[50]));
assert!(!v.starts_with(&[10, 50]));
Run如果 needle
为空切片,则始终返回 true
:
let v = &[10, 40, 30];
assert!(v.starts_with(&[]));
let v: &[u8] = &[];
assert!(v.starts_with(&[]));
Run如果 needle
是切片的后缀,则返回 true
。
Examples
let v = [10, 40, 30];
assert!(v.ends_with(&[30]));
assert!(v.ends_with(&[40, 30]));
assert!(!v.ends_with(&[50]));
assert!(!v.ends_with(&[50, 30]));
Run如果 needle
为空切片,则始终返回 true
:
let v = &[10, 40, 30];
assert!(v.ends_with(&[]));
let v: &[u8] = &[];
assert!(v.ends_with(&[]));
Run1.51.0[src]pub fn strip_prefix<P>(&self, prefix: &P) -> Option<&[T]> where
P: SlicePattern<Item = T> + ?Sized,
T: PartialEq<T>,
pub fn strip_prefix<P>(&self, prefix: &P) -> Option<&[T]> where
P: SlicePattern<Item = T> + ?Sized,
T: PartialEq<T>,
返回带有删除的前缀的子切片。
如果切片以 prefix
开头,则返回前缀在 Some
中的子切片。
如果 prefix
为空,则只需返回原始切片。
如果切片不是以 prefix
开头,则返回 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(&[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()));
Run1.51.0[src]pub fn strip_suffix<P>(&self, suffix: &P) -> Option<&[T]> where
P: SlicePattern<Item = T> + ?Sized,
T: PartialEq<T>,
pub fn strip_suffix<P>(&self, suffix: &P) -> Option<&[T]> where
P: SlicePattern<Item = T> + ?Sized,
T: PartialEq<T>,
返回删除后缀的子分片。
如果切片以 suffix
结尾,则返回后缀在 Some
中的子切片。
如果 suffix
为空,则只需返回原始切片。
如果切片不以 suffix
结尾,则返回 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(&[50]), None);
assert_eq!(v.strip_suffix(&[50, 30]), None);
RunBinary 在排序后的切片中搜索给定的元素。
如果找到该值,则返回 Result::Ok
,其中包含匹配元素的索引。
如果有多个匹配项,则可以返回任何一个匹配项。
索引的选择是确定的,但在 Rust 的未来版本中可能会发生变化。
如果找不到该值,则返回 Result::Err
,其中包含在保留排序顺序的同时可以在其中插入匹配元素的索引。
另请参见 binary_search_by
,binary_search_by_key
和 partition_point
。
Examples
查找一系列四个元素。
找到第一个,具有唯一确定的位置; 没有找到第二个和第三个; 第四个可以匹配 [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, });
Run如果要在排序的 vector 中插入项目,同时保持排序顺序,请执行以下操作:
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
let num = 42;
let idx = s.binary_search(&num).unwrap_or_else(|x| x);
s.insert(idx, num);
assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
RunBinary 使用比较器函数搜索排序后的切片。
comparator 函数应该实现一个与底层切片的排序顺序一致的顺序,返回一个顺序代码,并指示其参数期望的目标是 Less
,Equal
还是 Greater
。
如果找到该值,则返回 Result::Ok
,其中包含匹配元素的索引。如果有多个匹配项,则可以返回任何一个匹配项。
索引的选择是确定的,但在 Rust 的未来版本中可能会发生变化。
如果找不到该值,则返回 Result::Err
,其中包含在保留排序顺序的同时可以在其中插入匹配元素的索引。
另请参见 binary_search
,binary_search_by_key
和 partition_point
。
Examples
查找一系列四个元素。找到第一个,具有唯一确定的位置; 没有找到第二个和第三个; 第四个可以匹配 [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, });
RunBinary 使用关键字提取函数搜索排序后的切片。
假定按关键字对切片进行排序,例如使用相同的关键字提取函数对 sort_by_key
进行排序。
如果找到该值,则返回 Result::Ok
,其中包含匹配元素的索引。
如果有多个匹配项,则可以返回任何一个匹配项。
索引的选择是确定的,但在 Rust 的未来版本中可能会发生变化。
如果找不到该值,则返回 Result::Err
,其中包含在保留排序顺序的同时可以在其中插入匹配元素的索引。
另请参见 binary_search
,binary_search_by
和 partition_point
。
Examples
在成对的切片中按其第二个元素排序的一系列四个元素中查找。
找到第一个,具有唯一确定的位置; 没有找到第二个和第三个; 第四个可以匹配 [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, });
Run对三个元素进行排序,但可能不保留相等元素的顺序。
这种排序是不稳定的 (即可能重新排序相等的元素),就地 (即不分配) 和 O(n*log(* n*)) 最坏的情况)。
当前实现
当前算法基于 Orson Peters 的 pattern-defeating 的快速排序,该算法将随机快速排序的快速平均情况与堆排序的快速最坏情况相结合,同时在具有特定模式的切片上实现了线性时间。 它使用一些随机化来避免退化的情况,但是使用固定的 seed 来始终提供确定性的行为。
除了在一些特殊情况下 (例如,当切片由多个串联的排序序列组成) 以外,它通常比稳定排序快。
Examples
let mut v = [-5, 4, 1, -3, 2];
v.sort_unstable();
assert!(v == [-5, -3, 1, 2, 4]);
Run使用比较器函数对三元进行排序,但可能不保留相等元素的顺序。
这种排序是不稳定的 (即可能重新排序相等的元素),就地 (即不分配) 和 O(n*log(* n*)) 最坏的情况)。
比较器函数必须为切片中的元素定义总顺序。如果排序不全,则元素的顺序是未指定的。如果一个顺序是 (对于所有的a
, b
和 c
),那么它就是一个总体顺序
- 完全和反对称的:
a < b
,a == b
或a > b
之一正确,并且 - 可传递的,
a < b
和b < c
表示a < c
。==
和>
必须保持相同。
例如,虽然 f64
由于 NaN != NaN
而不实现 Ord
,但是当我们知道切片不包含 NaN
时,可以将 partial_cmp
用作我们的排序函数。
let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
floats.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
Run当前实现
当前算法基于 Orson Peters 的 pattern-defeating 的快速排序,该算法将随机快速排序的快速平均情况与堆排序的快速最坏情况相结合,同时在具有特定模式的切片上实现了线性时间。 它使用一些随机化来避免退化的情况,但是使用固定的 seed 来始终提供确定性的行为。
除了在一些特殊情况下 (例如,当切片由多个串联的排序序列组成) 以外,它通常比稳定排序快。
Examples
let mut v = [5, 4, 1, 3, 2];
v.sort_unstable_by(|a, b| a.cmp(b));
assert!(v == [1, 2, 3, 4, 5]);
// 反向排序
v.sort_unstable_by(|a, b| b.cmp(a));
assert!(v == [5, 4, 3, 2, 1]);
Run使用键提取函数对三个元素进行排序,但可能不保留相等元素的顺序。
这种排序是不稳定的 (即可能重新排序相等的元素),就地 (即不分配) 和 O(m* * n ** log(n)) 最坏的情况,其中键函数为 O(m)。
当前实现
当前算法基于 Orson Peters 的 pattern-defeating 的快速排序,该算法将随机快速排序的快速平均情况与堆排序的快速最坏情况相结合,同时在具有特定模式的切片上实现了线性时间。 它使用一些随机化来避免退化的情况,但是使用固定的 seed 来始终提供确定性的行为。
由于其键调用策略,在键函数很昂贵的情况下,sort_unstable_by_key
可能比 sort_by_cached_key
慢。
Examples
let mut v = [-5i32, 4, 1, -3, 2];
v.sort_unstable_by_key(|k| k.abs());
assert!(v == [1, 2, -3, 4, -5]);
Run👎 Deprecated since 1.49.0: use the select_nth_unstable() instead
use the select_nth_unstable() instead
重新排序切片,以使 index
处的元素处于其最终排序位置。
pub fn partition_at_index_by<F>(
&mut self,
index: usize,
compare: F
) -> (&mut [T], &mut T, &mut [T]) where
F: FnMut(&T, &T) -> Ordering,
👎 Deprecated since 1.49.0: use select_nth_unstable_by() instead
pub fn partition_at_index_by<F>(
&mut self,
index: usize,
compare: F
) -> (&mut [T], &mut T, &mut [T]) where
F: FnMut(&T, &T) -> Ordering,
use select_nth_unstable_by() instead
使用比较器函数对切片进行重新排序,以使 index
处的元素处于其最终排序位置。
pub fn partition_at_index_by_key<K, F>(
&mut self,
index: usize,
f: F
) -> (&mut [T], &mut T, &mut [T]) where
F: FnMut(&T) -> K,
K: Ord,
👎 Deprecated since 1.49.0: use the select_nth_unstable_by_key() instead
pub fn partition_at_index_by_key<K, F>(
&mut self,
index: usize,
f: F
) -> (&mut [T], &mut T, &mut [T]) where
F: FnMut(&T) -> K,
K: Ord,
use the select_nth_unstable_by_key() instead
使用键提取函数对切片进行重新排序,以使 index
处的元素处于其最终排序位置。
重新排序切片,以使 index
处的元素处于其最终排序位置。
此重新排序具有附加属性,即位置 i < index
处的任何值都将小于或等于位置 j > index
处的任何值。
此外,这种重新排序是不稳定的 (即
任何数量的相等元素都可以在位置 index
处就位 (即
不分配),以及 O(n) 最坏的情况。
在其他库中,该函数也被称为 “kth element”。
它返回以下值的三元组:所有元素在给定索引处小于一个,在给定索引处的值,以及所有在给定索引处大于一个的元素。
当前实现
当前算法基于用于 sort_unstable
的相同 quicksort 算法的 quickselect 部分。
Panics
index >= len()
时为 Panics,这意味着在空片上始终为 panics。
Examples
let mut v = [-5i32, 4, 1, -3, 2];
// 找到中位数
v.select_nth_unstable(2);
// 根据我们对指定索引的排序方式,我们仅保证切片将是以下内容之一。
assert!(v == [-3, -5, 1, 2, 4] ||
v == [-5, -3, 1, 2, 4] ||
v == [-3, -5, 1, 4, 2] ||
v == [-5, -3, 1, 4, 2]);
Run使用比较器函数对切片进行重新排序,以使 index
处的元素处于其最终排序位置。
此重排序具有附加属性,即使用比较器函数,位置 i < index
处的任何值将小于或等于位置 j > index
处的任何值。
另外,这种重新排序是不稳定的 (即,任意数量的相等元素可能会在位置 index
处结束),就地 (即,未分配) 和 O(n) 最坏的情况。
此函数在其他库中也称为 “kth element”。
它使用提供的比较器函数返回以下值的三元组:所有元素小于给定索引处的元素,给定索引处的值以及所有元素大于给定索引处的元素。
当前实现
当前算法基于用于 sort_unstable
的相同 quicksort 算法的 quickselect 部分。
Panics
index >= len()
时为 Panics,这意味着在空片上始终为 panics。
Examples
let mut v = [-5i32, 4, 1, -3, 2];
// 查找中间值,好像切片是按降序排序的。
v.select_nth_unstable_by(2, |a, b| b.cmp(a));
// 根据我们对指定索引的排序方式,我们仅保证切片将是以下内容之一。
assert!(v == [2, 4, 1, -5, -3] ||
v == [2, 4, 1, -3, -5] ||
v == [4, 2, 1, -5, -3] ||
v == [4, 2, 1, -3, -5]);
Run使用键提取函数对切片进行重新排序,以使 index
处的元素处于其最终排序位置。
此重新排序具有附加属性,即使用键提取函数,位置 i < index
处的任何值将小于或等于位置 j > index
处的任何值。
另外,这种重新排序是不稳定的 (即,任意数量的相等元素可能会在位置 index
处结束),就地 (即,未分配) 和 O(n) 最坏的情况。
此函数在其他库中也称为 “kth element”。
它使用提供的键提取函数返回以下值的三元组:所有元素小于给定索引处的元素,给定索引处的值以及所有元素大于给定索引处的元素。
当前实现
当前算法基于用于 sort_unstable
的相同 quicksort 算法的 quickselect 部分。
Panics
index >= len()
时为 Panics,这意味着在空片上始终为 panics。
Examples
let mut v = [-5i32, 4, 1, -3, 2];
// 返回中间值,就好像数组是根据绝对值排序的一样。
v.select_nth_unstable_by_key(2, |a| a.abs());
// 根据我们对指定索引的排序方式,我们仅保证切片将是以下内容之一。
assert!(v == [1, 2, -3, 4, -5] ||
v == [1, 2, -3, -5, 4] ||
v == [2, 1, -3, 4, -5] ||
v == [2, 1, -3, -5, 4]);
Run根据 PartialEq
trait 实现,将所有连续的重复元素移动到切片的末尾。
返回两个切片。第一个不包含连续的重复元素。 第二个包含没有指定顺序的所有重复项。
如果对切片进行排序,则第一个返回的切片不包含重复项。
Examples
#![feature(slice_partition_dedup)]
let mut slice = [1, 2, 2, 3, 3, 2, 1, 1];
let (dedup, duplicates) = slice.partition_dedup();
assert_eq!(dedup, [1, 2, 3, 2, 1]);
assert_eq!(duplicates, [2, 3, 1]);
Runpub fn partition_dedup_by<F>(&mut self, same_bucket: F) -> (&mut [T], &mut [T]) where
F: FnMut(&mut T, &mut T) -> bool,
pub fn partition_dedup_by<F>(&mut self, same_bucket: F) -> (&mut [T], &mut [T]) where
F: FnMut(&mut T, &mut T) -> bool,
将除第一个连续元素之外的所有元素移动到满足给定相等关系的切片的末尾。
返回两个切片。第一个不包含连续的重复元素。 第二个包含没有指定顺序的所有重复项。
same_bucket
函数被引用传递给切片中的两个元素,并且必须确定这些元素是否相等。
元素以与它们在切片中的顺序相反的顺序传递,因此,如果 same_bucket(a, b)
返回 true
,则 a
将在切片的末尾移动。
如果对切片进行排序,则第一个返回的切片不包含重复项。
Examples
#![feature(slice_partition_dedup)]
let mut slice = ["foo", "Foo", "BAZ", "Bar", "bar", "baz", "BAZ"];
let (dedup, duplicates) = slice.partition_dedup_by(|a, b| a.eq_ignore_ascii_case(b));
assert_eq!(dedup, ["foo", "BAZ", "Bar", "baz"]);
assert_eq!(duplicates, ["bar", "Foo", "BAZ"]);
Runpub fn partition_dedup_by_key<K, F>(&mut self, key: F) -> (&mut [T], &mut [T]) where
F: FnMut(&mut T) -> K,
K: PartialEq<K>,
pub fn partition_dedup_by_key<K, F>(&mut self, key: F) -> (&mut [T], &mut [T]) where
F: FnMut(&mut T) -> K,
K: PartialEq<K>,
将除了第一个连续元素之外的所有元素移动到解析为相同键的切片的末尾。
返回两个切片。第一个不包含连续的重复元素。 第二个包含没有指定顺序的所有重复项。
如果对切片进行排序,则第一个返回的切片不包含重复项。
Examples
#![feature(slice_partition_dedup)]
let mut slice = [10, 20, 21, 30, 30, 20, 11, 13];
let (dedup, duplicates) = slice.partition_dedup_by_key(|i| *i / 10);
assert_eq!(dedup, [10, 20, 30, 20, 11]);
assert_eq!(duplicates, [21, 30, 13]);
Run就地旋转切片,以使切片的第一个 mid
元素移至末尾,而最后一个 self.len() - mid
元素移至前端。
调用 rotate_left
后,先前在索引 mid
处的元素将成为切片中的第一个元素。
Panics
如果 mid
大于切片的长度,则此函数将为 panic。请注意,mid == self.len()
执行 not panic,并且是无操作旋转。
Complexity
花费线性时间 (以 self.len()
为单位)。
Examples
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
a.rotate_left(2);
assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
Run旋转子切片:
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
a[1..5].rotate_left(1);
assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']);
Run就地旋转切片,以使切片的第一个 self.len() - k
元素移至末尾,而最后一个 k
元素移至前端。
调用 rotate_right
后,先前在索引 self.len() - k
处的元素将成为切片中的第一个元素。
Panics
如果 k
大于切片的长度,则此函数将为 panic。请注意,k == self.len()
执行 not panic,并且是无操作旋转。
Complexity
花费线性时间 (以 self.len()
为单位)。
Examples
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
a.rotate_right(2);
assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']);
Run旋转子切片:
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
a[1..5].rotate_right(1);
assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']);
Run将元素从 src
复制到 self
。
src
的长度必须与 self
相同。
Panics
如果两个切片的长度不同,则此函数将为 panic。
Examples
将一个切片中的两个元素克隆到另一个中:
let src = [1, 2, 3, 4];
let mut dst = [0, 0];
// 由于切片必须具有相同的长度,因此我们将源切片从四个元素切成两个。
// 如果不这样做,它将为 panic。
dst.clone_from_slice(&src[2..]);
assert_eq!(src, [1, 2, 3, 4]);
assert_eq!(dst, [3, 4]);
RunRust 强制规定在特定范围内只能有一个可变引用,而没有对特定数据段的不可变引用。
因此,尝试在单个切片上使用 clone_from_slice
将导致编译失败:
let mut slice = [1, 2, 3, 4, 5];
slice[..2].clone_from_slice(&slice[3..]); // 编译失败!
Run要解决此问题,我们可以使用 split_at_mut
从切片创建两个不同的子切片:
let mut slice = [1, 2, 3, 4, 5];
{
let (left, right) = slice.split_at_mut(2);
left.clone_from_slice(&right[1..]);
}
assert_eq!(slice, [4, 5, 3, 4, 5]);
Run使用 memcpy 将所有元素从 src
复制到 self
。
src
的长度必须与 self
相同。
如果 T
未实现 Copy
,请使用 clone_from_slice
。
Panics
如果两个切片的长度不同,则此函数将为 panic。
Examples
将切片中的两个元素复制到另一个中:
let src = [1, 2, 3, 4];
let mut dst = [0, 0];
// 由于切片必须具有相同的长度,因此我们将源切片从四个元素切成两个。
// 如果不这样做,它将为 panic。
dst.copy_from_slice(&src[2..]);
assert_eq!(src, [1, 2, 3, 4]);
assert_eq!(dst, [3, 4]);
RunRust 强制规定在特定范围内只能有一个可变引用,而没有对特定数据段的不可变引用。
因此,尝试在单个切片上使用 copy_from_slice
将导致编译失败:
let mut slice = [1, 2, 3, 4, 5];
slice[..2].copy_from_slice(&slice[3..]); // 编译失败!
Run要解决此问题,我们可以使用 split_at_mut
从切片创建两个不同的子切片:
let mut slice = [1, 2, 3, 4, 5];
{
let (left, right) = slice.split_at_mut(2);
left.copy_from_slice(&right[1..]);
}
assert_eq!(slice, [4, 5, 3, 4, 5]);
Run1.37.0[src]pub fn copy_within<R>(&mut self, src: R, dest: usize) where
R: RangeBounds<usize>,
T: Copy,
pub fn copy_within<R>(&mut self, src: R, dest: usize) where
R: RangeBounds<usize>,
T: Copy,
使用记忆膜将元素从切片的一部分复制到自身的另一部分。
src
是 self
内要复制的范围。
dest
是要复制到的 self
范围内的起始索引,其长度与 src
相同。
这两个范围可能会重叠。
两个范围的末端必须小于或等于 self.len()
。
Panics
如果任一范围超出了切片的末尾,或者 src
的末尾在开始点之前,则此函数将为 panic。
Examples
在切片中复制四个字节:
let mut bytes = *b"Hello, World!";
bytes.copy_within(1..5, 8);
assert_eq!(&bytes, b"Hello, Wello!");
Run交换 self
中的所有元素和 other
中的所有元素。
other
的长度必须与 self
相同。
Panics
如果两个切片的长度不同,则此函数将为 panic。
Example
在切片之间交换两个元素:
let mut slice1 = [0, 0];
let mut slice2 = [1, 2, 3, 4];
slice1.swap_with_slice(&mut slice2[2..]);
assert_eq!(slice1, [3, 4]);
assert_eq!(slice2, [1, 2, 0, 0]);
RunRust 强制规定在特定范围内只能有一个对特定数据的可变引用。
因此,尝试在单个切片上使用 swap_with_slice
将导致编译失败:
let mut slice = [1, 2, 3, 4, 5];
slice[..2].swap_with_slice(&mut slice[3..]); // 编译失败!
Run要解决此问题,我们可以使用 split_at_mut
从切片创建两个不同的可变子切片:
let mut slice = [1, 2, 3, 4, 5];
{
let (left, right) = slice.split_at_mut(2);
left.swap_with_slice(&mut right[1..]);
}
assert_eq!(slice, [4, 5, 3, 1, 2]);
Run将切片转换为其他类型的切片,以确保保持类型的对齐。
此方法将切片分为三个不同的切片:前缀,正确对齐的新类型的中间切片和后缀切片。 该方法可以使中间切片对于给定类型和输入切片的最大长度成为可能,但是仅算法的性能应取决于此,而不取决于其正确性。
允许所有输入数据作为前缀或后缀切片返回。
当输入元素 T
或输出元素 U
的大小为零时,此方法无用,并且将返回原始切片而不拆分任何内容。
Safety
对于返回的中间切片中的元素,此方法本质上是 transmute
,因此,与 transmute::<T, U>
有关的所有常见警告也适用于此。
Examples
基本用法:
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);
}
Run将切片转换为其他类型的切片,以确保保持类型的对齐。
此方法将切片分为三个不同的切片:前缀,正确对齐的新类型的中间切片和后缀切片。 该方法可以使中间切片对于给定类型和输入切片的最大长度成为可能,但是仅算法的性能应取决于此,而不取决于其正确性。
允许所有输入数据作为前缀或后缀切片返回。
当输入元素 T
或输出元素 U
的大小为零时,此方法无用,并且将返回原始切片而不拆分任何内容。
Safety
对于返回的中间切片中的元素,此方法本质上是 transmute
,因此,与 transmute::<T, U>
有关的所有常见警告也适用于此。
Examples
基本用法:
unsafe {
let mut bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
let (prefix, shorts, suffix) = bytes.align_to_mut::<u16>();
// less_efficient_algorithm_for_bytes(prefix);
// more_efficient_algorithm_for_aligned_shorts(shorts);
// less_efficient_algorithm_for_bytes(suffix);
}
Runpub fn as_simd<const LANES: usize>(&self) -> (&[T], &[Simd<T, LANES>], &[T]) where
T: SimdElement,
Simd<T, LANES>: AsRef<[T; LANES]>,
LaneCount<LANES>: SupportedLaneCount,
pub fn as_simd<const LANES: usize>(&self) -> (&[T], &[Simd<T, LANES>], &[T]) where
T: SimdElement,
Simd<T, LANES>: AsRef<[T; LANES]>,
LaneCount<LANES>: SupportedLaneCount,
将切片分成前缀、中间对齐的 SIMD 类型和后缀。
这是一个围绕 slice::align_to
的安全包装器,因此具有与该方法相同的弱后置条件。
您只需要保证 self.len() == prefix.len() + middle.len() * LANES + suffix.len()
。
值得注意的是,以下所有情况都是可能的:
prefix.len() >= LANES
.middle.is_empty()
尽管self.len() >= 3 * LANES
。suffix.len() >= LANES
.
也就是说,这是一个安全的方法,所以如果您只编写安全的代码,那么这最多会导致不正确的逻辑,而不是不健全的。
Panics
如果 SIMD 类型的大小不同于标量的 LANES
倍,就会出现 panic。
在撰写本文时,Simd<T, LANES>
上的 trait 限制使这种情况永远不会发生,因为仅支持 2 的幂的 lanes 数。
有可能在未来的时候,这些限制可能会以某种方式取消,这样就有可能看到类似 LANES == 3
的 panics。
Examples
#![feature(portable_simd)]
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;
use std::simd::f32x4;
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.horizontal_sum()
}
let numbers: Vec<f32> = (1..101).map(|x| x as _).collect();
assert_eq!(basic_simd_sum(&numbers[1..99]), 4949.0);
Runpub fn as_simd_mut<const LANES: usize>(
&mut self
) -> (&mut [T], &mut [Simd<T, LANES>], &mut [T]) where
T: SimdElement,
Simd<T, LANES>: AsMut<[T; LANES]>,
LaneCount<LANES>: SupportedLaneCount,
pub fn as_simd_mut<const LANES: usize>(
&mut self
) -> (&mut [T], &mut [Simd<T, LANES>], &mut [T]) where
T: SimdElement,
Simd<T, LANES>: AsMut<[T; LANES]>,
LaneCount<LANES>: SupportedLaneCount,
将切片分成前缀、中间对齐的 SIMD 类型和后缀。
这是一个围绕 slice::align_to_mut
的安全包装器,因此具有与该方法相同的弱后置条件。
您只需要保证 self.len() == prefix.len() + middle.len() * LANES + suffix.len()
。
值得注意的是,以下所有情况都是可能的:
prefix.len() >= LANES
.middle.is_empty()
尽管self.len() >= 3 * LANES
。suffix.len() >= LANES
.
也就是说,这是一个安全的方法,所以如果您只编写安全的代码,那么这最多会导致不正确的逻辑,而不是不健全的。
这是 slice::as_simd
的可变版本; 请看这个例子。
Panics
如果 SIMD 类型的大小不同于标量的 LANES
倍,就会出现 panic。
在撰写本文时,Simd<T, LANES>
上的 trait 限制使这种情况永远不会发生,因为仅支持 2 的幂的 lanes 数。
有可能在未来的时候,这些限制可能会以某种方式取消,这样就有可能看到类似 LANES == 3
的 panics。
检查此切片的元素是否已排序。
也就是说,对于每个元素 a
及其后续元素 b
,a <= b
必须成立。如果切片产生恰好产生零个或一个元素,则返回 true
。
请注意,如果 Self::Item
仅是 PartialOrd
,而不是 Ord
,则上述定义意味着,如果任何两个连续的项都不具有可比性,则此函数将返回 false
。
Examples
#![feature(is_sorted)]
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());
Run检查此切片的元素是否使用给定的比较器函数进行排序。
该函数使用给定的 compare
函数来确定两个元素的顺序,而不是使用 PartialOrd::partial_cmp
。
除此之外,它等效于 is_sorted
。有关更多信息,请参见其文档。
根据给定的谓词返回分区点的索引 (第二个分区的第一个元素的索引)。
假定切片根据给定的谓词进行了分区。 这意味着谓词返回 true 的所有元素都在切片的开头,谓词返回 false 的所有元素都在切片的结尾。
例如,[7, 15, 3, 5, 4, 12, 6] 在谓词 x % 2 != 0
下进行了分区 (所有的奇数都在开头,所有的偶数都在结尾)。
如果未对该切片进行分区,则返回的结果是不确定的且无意义的,因为此方法执行一种二进制搜索。
另请参见 binary_search
,binary_search_by
和 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)));
Run删除与给定范围对应的子切片,并返回对它的引用。
如果给定的范围越界,则返回 None
并且不修改切片。
请注意,此方法仅接受 2..
或 ..6
等单侧范围,但不接受 2..6
。
Examples
获取切片的前三个元素:
#![feature(slice_take)]
let mut slice: &[_] = &['a', 'b', 'c', 'd'];
let mut first_three = slice.take(..3).unwrap();
assert_eq!(slice, &['d']);
assert_eq!(first_three, &['a', 'b', 'c']);
Run获取切片的最后两个元素:
#![feature(slice_take)]
let mut slice: &[_] = &['a', 'b', 'c', 'd'];
let mut tail = slice.take(2..).unwrap();
assert_eq!(slice, &['a', 'b']);
assert_eq!(tail, &['c', 'd']);
Run当 range
越界时会得到 None
:
#![feature(slice_take)]
let mut slice: &[_] = &['a', 'b', 'c', 'd'];
assert_eq!(None, slice.take(5..));
assert_eq!(None, slice.take(..5));
assert_eq!(None, slice.take(..=4));
let expected: &[char] = &['a', 'b', 'c', 'd'];
assert_eq!(Some(expected), slice.take(..4));
Runpub fn take_mut<R>(self: &mut &'a mut [T], range: R) -> Option<&'a mut [T]> where
R: OneSidedRange<usize>,
pub fn take_mut<R>(self: &mut &'a mut [T], range: R) -> Option<&'a mut [T]> where
R: OneSidedRange<usize>,
删除与给定范围对应的子切片,并返回对它的可变引用。
如果给定的范围越界,则返回 None
并且不修改切片。
请注意,此方法仅接受 2..
或 ..6
等单侧范围,但不接受 2..6
。
Examples
获取切片的前三个元素:
#![feature(slice_take)]
let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
let mut first_three = slice.take_mut(..3).unwrap();
assert_eq!(slice, &mut ['d']);
assert_eq!(first_three, &mut ['a', 'b', 'c']);
Run获取切片的最后两个元素:
#![feature(slice_take)]
let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
let mut tail = slice.take_mut(2..).unwrap();
assert_eq!(slice, &mut ['a', 'b']);
assert_eq!(tail, &mut ['c', 'd']);
Run当 range
越界时会得到 None
:
#![feature(slice_take)]
let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
assert_eq!(None, slice.take_mut(5..));
assert_eq!(None, slice.take_mut(..5));
assert_eq!(None, slice.take_mut(..=4));
let expected: &mut [_] = &mut ['a', 'b', 'c', 'd'];
assert_eq!(Some(expected), slice.take_mut(..4));
Run检查两个片是否是 ASCII 大小写不敏感的匹配项。
与 to_ascii_lowercase(a) == to_ascii_lowercase(b)
相同,但不分配和复制临时文件。
将该切片原位转换为其 ASCII 大写形式。
ASCII 字母 ‘a’ 到 ‘z’ 映射到 ‘A’ 到 ‘Z’,但是非 ASCII 字母不变。
要返回新的大写值而不修改现有值,请使用 to_ascii_uppercase
。
将该切片原位转换为其 ASCII 小写等效项。
ASCII 字母 ‘A’ 到 ‘Z’ 映射到 ‘a’ 到 ‘z’,但是非 ASCII 字母不变。
要返回新的小写值而不修改现有值,请使用 to_ascii_lowercase
。
pub fn escape_ascii(&self) -> EscapeAscii<'_>ⓘNotable traits for EscapeAscii<'a>impl<'a> Iterator for EscapeAscii<'a> type Item = u8;
pub fn escape_ascii(&self) -> EscapeAscii<'_>ⓘNotable traits for EscapeAscii<'a>impl<'a> Iterator for EscapeAscii<'a> type Item = u8;
impl<'a> Iterator for EscapeAscii<'a> type Item = u8;
对切片进行排序。
这种排序是稳定的 (即,不对相等的元素重新排序),并且 O(n*log(* n*)) 最坏的情况)。
在适用时,首选不稳定排序,因为它通常比稳定排序快,并且不分配辅助内存。
请参见 sort_unstable
。
当前实现
当前的算法是一种受 timsort 启发的自适应迭代合并排序。 在切片几乎被排序或由两个或多个依次连接的排序序列组成的情况下,它设计得非常快。
同样,它分配临时存储空间的大小是 self
的一半,但是对于短片,则使用非分配插入排序。
Examples
let mut v = [-5, 4, 1, -3, 2];
v.sort();
assert!(v == [-5, -3, 1, 2, 4]);
Run用比较器函数对切片进行排序。
这种排序是稳定的 (即,不对相等的元素重新排序),并且 O(n*log(* n*)) 最坏的情况)。
比较器函数必须为切片中的元素定义总顺序。如果排序不全,则元素的顺序是未指定的。
如果一个顺序是 (对于所有的a
, b
和 c
),那么它就是一个总体顺序
- 完全和反对称的:
a < b
,a == b
或a > b
之一正确,并且 - 可传递的,
a < b
和b < c
表示a < c
。==
和>
必须保持相同。
例如,虽然 f64
由于 NaN != NaN
而不实现 Ord
,但是当我们知道切片不包含 NaN
时,可以将 partial_cmp
用作我们的排序函数。
let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
floats.sort_by(|a, b| a.partial_cmp(b).unwrap());
assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
Run在适用时,首选不稳定排序,因为它通常比稳定排序快,并且不分配辅助内存。
请参见 sort_unstable_by
。
当前实现
当前的算法是一种受 timsort 启发的自适应迭代合并排序。 在切片几乎被排序或由两个或多个依次连接的排序序列组成的情况下,它设计得非常快。
同样,它分配临时存储空间的大小是 self
的一半,但是对于短片,则使用非分配插入排序。
Examples
let mut v = [5, 4, 1, 3, 2];
v.sort_by(|a, b| a.cmp(b));
assert!(v == [1, 2, 3, 4, 5]);
// 反向排序
v.sort_by(|a, b| b.cmp(a));
assert!(v == [5, 4, 3, 2, 1]);
Run用键提取函数对切片进行排序。
这种排序是稳定的 (即,不对相等的元素重新排序),并且是 O(m* * n ** log(n)) 最坏的情况,其中键函数为 O(m)。
对于昂贵的键函数 (例如
不是简单的属性访问或基本操作的函数),sort_by_cached_key
可能会显着提高速度,因为它不会重新计算元素键。
在适用时,首选不稳定排序,因为它通常比稳定排序快,并且不分配辅助内存。
请参见 sort_unstable_by_key
。
当前实现
当前的算法是一种受 timsort 启发的自适应迭代合并排序。 在切片几乎被排序或由两个或多个依次连接的排序序列组成的情况下,它设计得非常快。
同样,它分配临时存储空间的大小是 self
的一半,但是对于短片,则使用非分配插入排序。
Examples
let mut v = [-5i32, 4, 1, -3, 2];
v.sort_by_key(|k| k.abs());
assert!(v == [1, 2, -3, 4, -5]);
Run用键提取函数对切片进行排序。
在排序期间,键函数每个元素仅被调用一次。
这种排序是稳定的 (即,不对相等的元素重新排序),并且 O(m* * n + n ** log(n)) 最坏的情况是,其中键函数为 O(m)。
对于简单的键函数 (例如,作为属性访问或基本操作的函数),sort_by_key
可能会更快。
当前实现
当前算法基于 Orson Peters 的 pattern-defeating 的快速排序,该算法将随机快速排序的快速平均情况与堆排序的快速最坏情况相结合,同时在具有特定模式的切片上实现了线性时间。 它使用一些随机化来避免退化的情况,但是使用固定的 seed 来始终提供确定性的行为。
在最坏的情况下,该算法在 Vec<(K, usize)>
中分配切片长度的临时存储。
Examples
let mut v = [-5i32, 4, 32, -3, 2];
v.sort_by_cached_key(|k| k.to_string());
assert!(v == [-3, -5, 2, 32, 4]);
Run返回一个 vector,其中包含此切片的副本,其中每个字节都映射到其等效的 ASCII 大写字母。
ASCII 字母 ‘a’ 到 ‘z’ 映射到 ‘A’ 到 ‘Z’,但是非 ASCII 字母不变。
要就地将值大写,请使用 make_ascii_uppercase
。
Trait Implementations
impl<T, const LANES: usize> AsMut<[T]> for Simd<T, LANES> where
T: SimdElement,
LaneCount<LANES>: SupportedLaneCount,
impl<T, const LANES: usize> AsMut<[T]> for Simd<T, LANES> where
T: SimdElement,
LaneCount<LANES>: SupportedLaneCount,
impl<T, const LANES: usize> AsRef<[T]> for Simd<T, LANES> where
T: SimdElement,
LaneCount<LANES>: SupportedLaneCount,
impl<T, const LANES: usize> AsRef<[T]> for Simd<T, LANES> where
T: SimdElement,
LaneCount<LANES>: SupportedLaneCount,
串联后的结果类型
Note: Concat<str>
中的 str
在这里没有意义。
trait 的这个类型参数的存在只是为了启用另一个 impl。
pub fn from(slice: &[T]) -> Box<[T], Global>ⓘNotable traits for Box<I, A>impl<I, A> Iterator for Box<I, A> where
I: Iterator + ?Sized,
A: Allocator, type Item = <I as Iterator>::Item;impl<F, A> Future for Box<F, A> where
F: Future + Unpin + ?Sized,
A: Allocator + 'static, type Output = <F as Future>::Output;impl<R: Read + ?Sized> Read for Box<R>impl<W: Write + ?Sized> Write for Box<W>
pub fn from(slice: &[T]) -> Box<[T], Global>ⓘNotable traits for Box<I, A>impl<I, A> Iterator for Box<I, A> where
I: Iterator + ?Sized,
A: Allocator, type Item = <I as Iterator>::Item;impl<F, A> Future for Box<F, A> where
F: Future + Unpin + ?Sized,
A: Allocator + 'static, type Output = <F as Future>::Output;impl<R: Read + ?Sized> Read for Box<R>impl<W: Write + ?Sized> Write for Box<W>
impl<I, A> Iterator for Box<I, A> where
I: Iterator + ?Sized,
A: Allocator, type Item = <I as Iterator>::Item;impl<F, A> Future for Box<F, A> where
F: Future + Unpin + ?Sized,
A: Allocator + 'static, type Output = <F as Future>::Output;impl<R: Read + ?Sized> Read for Box<R>impl<W: Write + ?Sized> Write for Box<W>
串联后的结果类型
串联后的结果类型
搜索等于切片中任何 char
的字符。
Examples
assert_eq!("Hello world".find(&['l', 'l'] as &[_]), Some(2));
assert_eq!("Hello world".find(&['l', 'l'][..]), Some(2));
Run检查模式是否与 haystack 中的任何位置匹配
检查模式是否在 haystack 的前面匹配
如果匹配,则从 haystack 的正面删除模式。
pub fn is_suffix_of(self, haystack: &'a str) -> bool where
CharSliceSearcher<'a, 'b>: ReverseSearcher<'a>,
pub fn is_suffix_of(self, haystack: &'a str) -> bool where
CharSliceSearcher<'a, 'b>: ReverseSearcher<'a>,
检查模式是否与 haystack 的后面匹配
pub fn strip_suffix_of(self, haystack: &'a str) -> Option<&'a str> where
CharSliceSearcher<'a, 'b>: ReverseSearcher<'a>,
pub fn strip_suffix_of(self, haystack: &'a str) -> Option<&'a str> where
CharSliceSearcher<'a, 'b>: ReverseSearcher<'a>,
如果匹配,则从 haystack 的后面删除模式。
通过从切片复制为 &[u8]
实现读取。
请注意,读取将更新切片以指向尚未读取的部分。 到达 EOF 时,切片将为空。
与 read
相似,不同之处在于它读入缓冲区的一部分。 Read more
读取所有字节,直到此源中的 EOF 为止,然后将它们放入 buf
。 Read more
读取这个源中的所有字节,直到 EOF 为止,然后将它们追加到 buf
。 Read more
为这个 Read
实例创建一个 “by reference” 适配器。 Read more
创建一个适配器,将这个流与另一个链接起来。 Read more
slice_index_methods
)返回此位置输出的共享引用,而不执行任何边界检查。
即使未使用所得的引用,使用越界索引或悬垂的 slice
指针调用此方法也是 [undefined 行为]。 Read more
slice_index_methods
)返回此位置输出的变量引用,而不执行任何边界检查。
即使未使用所得的引用,使用越界索引或悬垂的 slice
指针调用此方法也是 [undefined 行为]。 Read more
slice_index_methods
)返回此位置输出的共享引用,如果越界则会触发 panic。 Read more
slice_index_methods
)返回此位置输出的共享引用,而不执行任何边界检查。
即使未使用所得的引用,使用越界索引或悬垂的 slice
指针调用此方法也是 [undefined 行为]。 Read more
slice_index_methods
)返回此位置输出的变量引用,而不执行任何边界检查。
即使未使用所得的引用,使用越界索引或悬垂的 slice
指针调用此方法也是 [undefined 行为]。 Read more
slice_index_methods
)返回此位置输出的共享引用,如果越界则会触发 panic。 Read more
slice_index_methods
)返回此位置输出的共享引用,而不执行任何边界检查。
即使未使用所得的引用,使用越界索引或悬垂的 slice
指针调用此方法也是 [undefined 行为]。 Read more
slice_index_methods
)返回此位置输出的变量引用,而不执行任何边界检查。
即使未使用所得的引用,使用越界索引或悬垂的 slice
指针调用此方法也是 [undefined 行为]。 Read more
slice_index_methods
)返回此位置输出的共享引用,如果越界则会触发 panic。 Read more
slice_index_methods
)返回此位置输出的共享引用,而不执行任何边界检查。
即使未使用所得的引用,使用越界索引或悬垂的 slice
指针调用此方法也是 [undefined 行为]。 Read more
slice_index_methods
)返回此位置输出的变量引用,而不执行任何边界检查。
即使未使用所得的引用,使用越界索引或悬垂的 slice
指针调用此方法也是 [undefined 行为]。 Read more
slice_index_methods
)返回此位置输出的共享引用,如果越界则会触发 panic。 Read more
slice_index_methods
)返回此位置输出的共享引用,而不执行任何边界检查。
即使未使用所得的引用,使用越界索引或悬垂的 slice
指针调用此方法也是 [undefined 行为]。 Read more
slice_index_methods
)返回此位置输出的变量引用,而不执行任何边界检查。
即使未使用所得的引用,使用越界索引或悬垂的 slice
指针调用此方法也是 [undefined 行为]。 Read more
slice_index_methods
)返回此位置输出的共享引用,如果越界则会触发 panic。 Read more
slice_index_methods
)返回此位置输出的共享引用,而不执行任何边界检查。
即使未使用所得的引用,使用越界索引或悬垂的 slice
指针调用此方法也是 [undefined 行为]。 Read more
slice_index_methods
)返回此位置输出的变量引用,而不执行任何边界检查。
即使未使用所得的引用,使用越界索引或悬垂的 slice
指针调用此方法也是 [undefined 行为]。 Read more
slice_index_methods
)返回此位置输出的共享引用,如果越界则会触发 panic。 Read more
type Output = T
type Output = T
方法返回的输出类型。
slice_index_methods
)返回此位置输出的共享引用,而不执行任何边界检查。
即使未使用所得的引用,使用越界索引或悬垂的 slice
指针调用此方法也是 [undefined 行为]。 Read more
slice_index_methods
)返回此位置输出的变量引用,而不执行任何边界检查。
即使未使用所得的引用,使用越界索引或悬垂的 slice
指针调用此方法也是 [undefined 行为]。 Read more
slice_index_methods
)返回此位置输出的共享引用,如果越界则会触发 panic。 Read more
slice_index_methods
)返回此位置输出的共享引用,而不执行任何边界检查。
即使未使用所得的引用,使用越界索引或悬垂的 slice
指针调用此方法也是 [undefined 行为]。 Read more
slice_index_methods
)返回此位置输出的变量引用,而不执行任何边界检查。
即使未使用所得的引用,使用越界索引或悬垂的 slice
指针调用此方法也是 [undefined 行为]。 Read more
slice_index_methods
)返回此位置输出的共享引用,如果越界则会触发 panic。 Read more
从借用的数据创建拥有的数据,通常是通过克隆。 Read more
type Iter = Cloned<Iter<'a, SocketAddr>>
type Iter = Cloned<Iter<'a, SocketAddr>>
在此类型可能对应的套接字地址上返回的迭代器。 Read more
将此对象转换为已解析的 SocketAddr
的迭代器。 Read more
type Error = TryFromSliceError
type Error = TryFromSliceError
发生转换错误时返回的类型。
type Error = TryFromSliceError
type Error = TryFromSliceError
发生转换错误时返回的类型。
type Error = TryFromSliceError
type Error = TryFromSliceError
发生转换错误时返回的类型。
type Error = TryFromSliceError
type Error = TryFromSliceError
发生转换错误时返回的类型。
通过将 &mut [u8]
复制到切片中并覆盖其数据来实现写入。
请注意,编写会更新切片以指向尚未编写的部分。 完全覆盖后,切片将为空。
如果要写入的字节数超过了切片的大小,则写入操作将返回短写入:最终为 Ok(0)
; 否则为 Ok(0)
。在这种情况下,write_all
返回类型为 ErrorKind::WriteZero
的错误。
将格式化的字符串写入此 writer,返回遇到的任何错误。 Read more