Struct std::vec::Vec 1.0.0[−][src]
Expand description
连续的可增长数组类型,写为 Vec<T>
,发音为 ‘vector’。
Examples
let mut vec = Vec::new(); vec.push(1); vec.push(2); assert_eq!(vec.len(), 2); assert_eq!(vec[0], 1); assert_eq!(vec.pop(), Some(2)); assert_eq!(vec.len(), 1); vec[0] = 7; assert_eq!(vec[0], 7); vec.extend([1, 2, 3].iter().copied()); for x in &vec { println!("{}", x); } assert_eq!(vec, [7, 1, 2, 3]);Run
提供 vec!
宏可以使初始化更加方便:
let mut vec = vec![1, 2, 3]; vec.push(4); assert_eq!(vec, [1, 2, 3, 4]);Run
它还可以使用给定值初始化 Vec<T>
的每个元素。
这可能比在单独的步骤中执行分配和初始化更为有效,尤其是在初始化零的 vector 时:
let vec = vec![0; 5]; assert_eq!(vec, [0, 0, 0, 0, 0]); // 以下是等效的,但可能会更慢: let mut vec = Vec::with_capacity(5); vec.resize(5, 0); assert_eq!(vec, [0, 0, 0, 0, 0]);Run
有关更多信息,请参见 容量和重新分配。
使用 Vec<T>
作为有效的栈:
let mut stack = Vec::new(); stack.push(1); stack.push(2); stack.push(3); while let Some(top) = stack.pop() { // 打印 3、2、1 println!("{}", top); }Run
Indexing
Vec
类型实现了 Index
trait,因此允许按索引访问值。一个例子将更加明确:
let v = vec![0, 2, 4, 6]; println!("{}", v[1]); // 它将显示 '2'Run
但是要小心: 如果您尝试访问 Vec
中没有的索引,则您的软件将为 panic! 您不可以做这个:
let v = vec![0, 2, 4, 6]; println!("{}", v[6]); // 它会 panic!Run
如果要检查索引是否在 Vec
中,请使用 get
和 get_mut
。
Slicing
Vec
可以是可变的。另一方面,切片是只读对象。
要获得 slice,请使用 &
。Example:
fn read_slice(slice: &[usize]) { // ... } let v = vec![0, 1]; read_slice(&v); // ... 就这样! // 您也可以这样: let u: &[usize] = &v; // 或像这样: let u: &[_] = &v;Run
在 Rust 中,当您只想提供读取访问权限时,将切片作为参数而不是 vectors 传递是更常见的。String
和 &str
也是如此。
容量和重新分配
vector 的容量是为将添加到 vector 上的任何 future 元素分配的空间量。请勿将其与 vector 的长度混淆,后者指定 vector 中的实际元素数量。 如果 vector 的长度超过其容量,则其容量将自动增加,但必须重新分配其元素。
例如,容量为 10 且长度为 0 的 vector 将是一个空的 vector,具有 10 个以上元素的空间。将 10 个或更少的元素压入 vector 不会改变其容量或引起重新分配。
但是,如果 vector 的长度增加到 11,则必须重新分配,这可能会很慢。因此,建议尽可能使用 Vec::with_capacity
来指定 vector 希望达到的大小。
Guarantees
由于其不可思议的基本特性,Vec
为其设计提供了很多保证。这样可以确保它在一般情况下的开销尽可能小,并且可以通过不安全的代码以原始方式正确地进行操作。请注意,这些保证是针对不合格的 Vec<T>
。
如果添加了其他类型参数 (例如,以支持自定义分配器),则覆盖其默认值可能会更改行为。
从根本上讲,Vec
始终是 (指针,容量,长度) 三元组。不多不少。这些字段的顺序是完全不确定的,您应该使用适当的方法来修改它们。
指针永远不会为空,因此此类型是经过空指针优化的。
但是,指针实际上可能并不指向分配的内存。
特别是,如果您通过 Vec::new
,vec![]
,Vec::with_capacity(0)
或通过在空 Vec 上调用 shrink_to_fit
来构造容量为 0 的 Vec
,则它将不会分配内存。同样,如果将零大小的类型存储在 Vec
内,则不会为它们分配空间。
Note 在这种情况下,Vec
可能不会报告 capacity
为 0。
Vec
将仅在 mem::size_of::<T>
() * capacity() > 0
时分配。
通常,Vec
的分配细节非常微妙 - 如果您打算使用 Vec
分配内存并将其用于其他用途 (传递给不安全的代码或构建自己的内存支持的集合),请确保通过使用 from_raw_parts
恢复 Vec
然后丢弃它来释放该内存。
如果 Vec
具有已分配的内存,则它指向的内存在堆上 (由分配器 Rust 定义为默认使用),并且其指针按顺序指向 len
初始化的连续元素 (您将执行的操作) 看看是否将其强制为切片),然后是 capacity
-
len
逻辑上未初始化的连续元素。
包含元素 'a'
和 'b'
且容量为 4 的 vector 可以如下所示。顶部是 Vec
结构体,它包含一个指向堆中分配头,长度和容量的指针。
底部是堆上的分配,即连续的内存块。
ptr len capacity
+--------+--------+--------+
| 0x0123 | 2 | 4 |
+--------+--------+--------+
|
v
Heap +--------+--------+--------+--------+
| 'a' | 'b' | uninit | uninit |
+--------+--------+--------+--------+
- uninit 代表未初始化的内存,请参见
MaybeUninit
。 - Note: ABI 不稳定,并且
Vec
不保证其内存布局 (包括字段顺序)。
Vec
永远不会执行小优化,因为实际上有两个原因会在其中将元素实际存储在栈中:
-
对于不安全的代码,正确地操纵
Vec
会更加困难。如果仅移动Vec
的内容,它的地址就不会稳定,因此,确定Vec
是否实际分配了内存将更加困难。 -
这将惩罚一般情况,每次访问都会产生一个额外的分支。
Vec
即使完全为空,也永远不会自动收缩。这样可以确保不会发生不必要的分配或释放。清空 Vec
,然后将其填充回相同的 len
,将不会引起对分配器的调用。如果您希望释放未使用的内存,请使用 shrink_to_fit
或 shrink_to
。
push
如果报告的容量足够,则 insert
将永远不会 (重新) 分配。如果 len
==
capacity
,push
和 insert
将 * (重新) 分配。也就是说,报告的容量是完全准确的,并且可以依赖。如果需要,它甚至可以用来手动释放 Vec
分配的内存。
批量插入方法 可能 重新分配,即使在没有必要时也是如此。
Vec
在完全分配或调用 reserve
时重新分配时,不能保证任何特定的增长策略。当前的策略是基本的,使用非恒定增长因子可能是合乎需要的。无论使用哪种策略,当然都可以保证 O(1) 摊销 push
。
vec![x; n]
, vec![a, b, c, d]
和 Vec::with_capacity(n)
都将产生具有所需容量的 Vec
。
如果 len
==
capacity
(如 vec!
宏的情况),那么 Vec<T>
可以与 Box<[T]>
相互转换,而无需重新分配或移动元素。
Vec
不会专门覆盖从其中删除的任何数据,但也不会专门保留它。它的未初始化内存是它可以使用的临时空间。通常,它只会执行最有效或最容易实现的任何事情。为了安全起见,请勿依赖删除的数据进行擦除。
即使您丢弃了 Vec
,它的缓冲区也可能被另一个 Vec
简单地重用。
即使您先将 Vec
的内存清零,这可能不会实际发生,因为优化器不认为这是一个必须保留的副作用。
但是,有一种情况我们不会中断: 使用 unsafe
代码写入多余的容量,然后增加长度以匹配,始终是有效的。
当前,Vec
不保证删除元素的顺序。
顺序过去已更改,并且可能会再次更改。
Implementations
创建一个具有指定容量的新的空 Vec<T>
。
vector 将能够准确地容纳 capacity
元素而无需重新分配。
如果 capacity
为 0,则不会分配 vector。
重要的是要注意,尽管返回的 vector 具有指定的 capacity,但 vector 的长度为零。
有关长度和容量之间差异的说明,请参见 [Capacity and 重新分配]。
Panics
如果新容量超过 isize::MAX
字节,则为 Panics。
Examples
let mut vec = Vec::with_capacity(10); // vector 不包含任何项,即使它具有更多功能 assert_eq!(vec.len(), 0); assert_eq!(vec.capacity(), 10); // 这些都无需重新分配即可完成... for i in 0..10 { vec.push(i); } assert_eq!(vec.len(), 10); assert_eq!(vec.capacity(), 10); // ... 但是这可能会使 vector 重新分配 vec.push(11); assert_eq!(vec.len(), 11); assert!(vec.capacity() >= 11);Run
直接从另一个 vector 的原始组件创建 Vec<T>
。
Safety
由于未检查的不可变变量数量,这是非常不安全的:
-
ptr
需要事先通过String
/Vec 分配 <T>
(至少,如果不是这样,很可能是不正确的)。 -
T
需要具有与分配给ptr
相同的大小和对齐方式。 (具有不太严格的对齐方式的T
是不够的,对齐方式实际上必须等于dealloc
的要求,即必须以相同的布局分配和释放内存。) -
length
必须小于或等于capacity
。 -
capacity
必须是分配指针的容量。
违反这些可能会导致一些问题,比如破坏分配器的内部数据结构。例如,从指向长度为 size_t
的 C char
数组的指针构建 Vec<u8>
是 ** 不安全的。
从 Vec<u16>
及其长度构建一个也不安全,因为分配器关心对齐方式,并且这两种类型具有不同的对齐方式。
缓冲区的分配是对齐 2 (对于 u16
),但是将其转换为 Vec<u8>
后,它将以对齐 1 释放。
ptr
的所有权有效地转移到 Vec<T>
,然后 Vec<T>
可以随意释放,重新分配或更改指针所指向的内存的内容。
调用此函数后,请确保没有其他任何东西使用该指针。
Examples
use std::ptr; use std::mem; let v = vec![1, 2, 3]; // 防止运行 `v` 的析构函数,因此我们可以完全控制分配。 let mut v = mem::ManuallyDrop::new(v); // Pull 有关 `v` 的各种重要信息 let p = v.as_mut_ptr(); let len = v.len(); let cap = v.capacity(); unsafe { // 用 4、5、6 覆盖内存 for i in 0..len as isize { ptr::write(p.offset(i), 4 + i); } // 将所有内容放回 Vec let rebuilt = Vec::from_raw_parts(p, len, cap); assert_eq!(rebuilt, [4, 5, 6]); }Run
使用提供的分配器构造具有指定容量的新的空 Vec<T, A>
。
vector 将能够准确地容纳 capacity
元素而无需重新分配。
如果 capacity
为 0,则不会分配 vector。
重要的是要注意,尽管返回的 vector 具有指定的 capacity,但 vector 的长度为零。
有关长度和容量之间差异的说明,请参见 [Capacity and 重新分配]。
Panics
如果新容量超过 isize::MAX
字节,则为 Panics。
Examples
#![feature(allocator_api)] use std::alloc::System; let mut vec = Vec::with_capacity_in(10, System); // vector 不包含任何项,即使它具有更多功能 assert_eq!(vec.len(), 0); assert_eq!(vec.capacity(), 10); // 这些都无需重新分配即可完成... for i in 0..10 { vec.push(i); } assert_eq!(vec.len(), 10); assert_eq!(vec.capacity(), 10); // ... 但是这可能会使 vector 重新分配 vec.push(11); assert_eq!(vec.len(), 11); assert!(vec.capacity() >= 11);Run
pub unsafe fn from_raw_parts_in(
ptr: *mut T,
length: usize,
capacity: usize,
alloc: A
) -> Vec<T, A>ⓘ
[src]
pub unsafe fn from_raw_parts_in(
ptr: *mut T,
length: usize,
capacity: usize,
alloc: A
) -> Vec<T, A>ⓘ
[src]直接从另一个 vector 的原始组件创建 Vec<T, A>
。
Safety
由于未检查的不可变变量数量,这是非常不安全的:
-
ptr
需要事先通过String
/Vec 分配 <T>
(至少,如果不是这样,很可能是不正确的)。 -
T
需要具有与分配给ptr
相同的大小和对齐方式。 (具有不太严格的对齐方式的T
是不够的,对齐方式实际上必须等于dealloc
的要求,即必须以相同的布局分配和释放内存。) -
length
必须小于或等于capacity
。 -
capacity
必须是分配指针的容量。
违反这些可能会导致一些问题,比如破坏分配器的内部数据结构。例如,从指向长度为 size_t
的 C char
数组的指针构建 Vec<u8>
是 ** 不安全的。
从 Vec<u16>
及其长度构建一个也不安全,因为分配器关心对齐方式,并且这两种类型具有不同的对齐方式。
缓冲区的分配是对齐 2 (对于 u16
),但是将其转换为 Vec<u8>
后,它将以对齐 1 释放。
ptr
的所有权有效地转移到 Vec<T>
,然后 Vec<T>
可以随意释放,重新分配或更改指针所指向的内存的内容。
调用此函数后,请确保没有其他任何东西使用该指针。
Examples
#![feature(allocator_api)] use std::alloc::System; use std::ptr; use std::mem; let mut v = Vec::with_capacity_in(3, System); v.push(1); v.push(2); v.push(3); // 防止运行 `v` 的析构函数,因此我们可以完全控制分配。 let mut v = mem::ManuallyDrop::new(v); // Pull 有关 `v` 的各种重要信息 let p = v.as_mut_ptr(); let len = v.len(); let cap = v.capacity(); let alloc = v.allocator(); unsafe { // 用 4、5、6 覆盖内存 for i in 0..len as isize { ptr::write(p.offset(i), 4 + i); } // 将所有内容放回 Vec let rebuilt = Vec::from_raw_parts_in(p, len, cap, alloc.clone()); assert_eq!(rebuilt, [4, 5, 6]); }Run
🔬 This is a nightly-only experimental API. (vec_into_raw_parts
#65816)
new API
🔬 This is a nightly-only experimental API. (vec_into_raw_parts
#65816)
new API
将 Vec<T>
分解为其原始组件。
返回基础数据的裸指针,vector 的长度 (以元素为单位) 和数据的已分配容量 (以元素为单位)。
这些参数与 from_raw_parts
的参数顺序相同。
调用此函数后,调用者负责 Vec
先前管理的内存。
唯一的方法是使用 from_raw_parts
函数将裸指针,长度和容量转换回 Vec
,从而允许析构函数执行清除操作。
Examples
#![feature(vec_into_raw_parts)] let v: Vec<i32> = vec![-1, 0, 1]; let (ptr, len, cap) = v.into_raw_parts(); let rebuilt = unsafe { // 现在,我们可以对组件进行更改,例如将裸指针转换为兼容类型。 let ptr = ptr as *mut u32; Vec::from_raw_parts(ptr, len, cap) }; assert_eq!(rebuilt, [4294967295, 0, 1]);Run
将 Vec<T>
分解为其原始组件。
返回基础数据的裸指针,vector 的长度 (以元素为单位),数据的已分配容量 (以元素为单位) 以及分配器。
这些参数与 from_raw_parts_in
的参数顺序相同。
调用此函数后,调用者负责 Vec
先前管理的内存。
唯一的方法是使用 from_raw_parts_in
函数将裸指针,长度和容量转换回 Vec
,从而允许析构函数执行清除操作。
Examples
#![feature(allocator_api, vec_into_raw_parts)] use std::alloc::System; let mut v: Vec<i32, System> = Vec::new_in(System); v.push(-1); v.push(0); v.push(1); let (ptr, len, cap, alloc) = v.into_raw_parts_with_alloc(); let rebuilt = unsafe { // 现在,我们可以对组件进行更改,例如将裸指针转换为兼容类型。 let ptr = ptr as *mut u32; Vec::from_raw_parts_in(ptr, len, cap, alloc) }; assert_eq!(rebuilt, [4294967295, 0, 1]);Run
保留最小容量,以便在给定的 Vec<T>
中精确插入 additional
个元素。
调用 reserve_exact
后,容量将大于或等于 self.len() + additional
。
如果容量已经足够,则不执行任何操作。
请注意,分配器可能会给集合提供比其请求更多的空间。
因此,不能依靠容量来精确地最小化。
如果希望将来插入,则最好使用 reserve
。
Panics
如果新容量溢出 usize
,则为 Panics。
Examples
let mut vec = vec![1]; vec.reserve_exact(10); assert!(vec.capacity() >= 11);Run
🔬 This is a nightly-only experimental API. (try_reserve
#48043)
new API
🔬 This is a nightly-only experimental API. (try_reserve
#48043)
new API
尝试为给 Vec<T>
至少插入 additional
个元素保留容量。
该集合可以保留更多空间,以避免频繁的重新分配。
调用 try_reserve
后,容量将大于或等于 self.len() + additional
。
如果容量已经足够,则不执行任何操作。
Errors
如果容量溢出,或者分配器报告失败,则返回错误。
Examples
#![feature(try_reserve)] use std::collections::TryReserveError; fn process_data(data: &[u32]) -> Result<Vec<u32>, TryReserveError> { let mut output = Vec::new(); // 预先保留内存,如果不能,则退出 output.try_reserve(data.len())?; // 现在我们知道在我们复杂的工作中这不能 OOM output.extend(data.iter().map(|&val| { val * 2 + 5 // 非常复杂 })); Ok(output) }Run
🔬 This is a nightly-only experimental API. (try_reserve
#48043)
new API
🔬 This is a nightly-only experimental API. (try_reserve
#48043)
new API
尝试保留将最小 additional
元素插入给定 Vec<T>
的最小容量。
调用 try_reserve_exact
后,如果返回 Ok(())
,则容量将大于或等于 self.len() + additional
。
如果容量已经足够,则不执行任何操作。
请注意,分配器可能会给集合提供比其请求更多的空间。
因此,不能依靠容量来精确地最小化。
如果希望将来插入,则最好使用 reserve
。
Errors
如果容量溢出,或者分配器报告失败,则返回错误。
Examples
#![feature(try_reserve)] use std::collections::TryReserveError; fn process_data(data: &[u32]) -> Result<Vec<u32>, TryReserveError> { let mut output = Vec::new(); // 预先保留内存,如果不能,则退出 output.try_reserve_exact(data.len())?; // 现在我们知道在我们复杂的工作中这不能 OOM output.extend(data.iter().map(|&val| { val * 2 + 5 // 非常复杂 })); Ok(output) }Run
🔬 This is a nightly-only experimental API. (shrink_to
#56431)
new API
🔬 This is a nightly-only experimental API. (shrink_to
#56431)
new API
pub fn into_boxed_slice(self) -> Box<[T], A>ⓘ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>
[src]
pub fn into_boxed_slice(self) -> Box<[T], A>ⓘ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>
[src]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>
缩短 vector,保留前 len
个元素,并丢弃其他元素。
如果 len
大于 vector 的当前长度,则无效。
drain
方法可以模拟 truncate
,但是会导致多余的元素被返回而不是丢弃。
请注意,此方法对 vector 的已分配容量没有影响。
Examples
将五个元素 vector 截断为两个元素:
let mut vec = vec![1, 2, 3, 4, 5]; vec.truncate(2); assert_eq!(vec, [1, 2]);Run
当 len
大于 vector 的当前长度时,不会发生截断:
let mut vec = vec![1, 2, 3]; vec.truncate(8); assert_eq!(vec, [1, 2, 3]);Run
在 len == 0
等效于调用 clear
方法时截断。
let mut vec = vec![1, 2, 3]; vec.truncate(0); assert_eq!(vec, []);Run
返回 vector 的缓冲区的裸指针。
调用者必须确保 vector 超过此函数返回的指针,否则它将最终指向垃圾。 修改 vector 可能会导致重新分配其缓冲区,这还会使指向该缓冲区的任何指针无效。
调用者还必须确保指针 (non-transitively) 所指向的内存 (从 UnsafeCell
内部除外) 永远不会使用此指针或从其派生的任何指针写入。
如果需要更改切片的内容,请使用 as_mut_ptr
。
Examples
let x = vec![1, 2, 4]; let x_ptr = x.as_ptr(); unsafe { for i in 0..x.len() { assert_eq!(*x_ptr.add(i), 1 << i); } }Run
返回指向 vector 缓冲区的不安全可变指针。
调用者必须确保 vector 超过此函数返回的指针,否则它将最终指向垃圾。
修改 vector 可能会导致重新分配其缓冲区,这还会使指向该缓冲区的任何指针无效。
Examples
// 分配足够大的 vector 以容纳 4 个元素。 let size = 4; let mut x: Vec<i32> = Vec::with_capacity(size); let x_ptr = x.as_mut_ptr(); // 通过裸指针写入初始化元素,然后设置长度。 unsafe { for i in 0..size { *x_ptr.add(i) = i as i32; } x.set_len(size); } assert_eq!(&*x, &[0, 1, 2, 3]);Run
返回基础分配器的引用。
将 vector 的长度强制为 new_len
。
这是一个维操作,不保留该类型的任何普通不变式。
通常,使用安全操作之一 (例如 truncate
,resize
,extend
或 clear
) 来更改 vector 的长度。
Safety
new_len
必须小于或等于capacity()
。old_len..new_len
上的元素必须初始化。
Examples
当 vector 用作其他代码的缓冲区时,尤其是在 FFI 上,此方法很有用:
pub fn get_dictionary(&self) -> Option<Vec<u8>> { // 根据 FFI 方法的文档, "32768 bytes is always enough". let mut dict = Vec::with_capacity(32_768); let mut dict_length = 0; // SAFETY: 当 `deflateGetDictionary` 返回 `Z_OK` 时,它认为: // 1. `dict_length` 元素已初始化。 // 2. // `dict_length` <= (32_768) 的容量使 `set_len` 可以安全调用。 unsafe { // 使 FFI 调用... let r = deflateGetDictionary(self.strm, dict.as_mut_ptr(), &mut dict_length); if r == Z_OK { // ... 并将长度更新为已初始化的长度。 dict.set_len(dict_length); Some(dict) } else { None } } }Run
尽管下面的示例是正确的,但由于 set_len
调用之前未释放内部 vectors,所以存在内存泄漏:
let mut vec = vec![vec![1, 0, 0], vec![0, 1, 0], vec![0, 0, 1]]; // SAFETY: // 1. `old_len..0` 为空,因此不需要初始化任何元素。 // 2. `0 <= capacity` 始终保留 `capacity` 是什么。 unsafe { vec.set_len(0); }Run
通常,在这里,人们将使用 clear
来正确丢弃内容,因此不会泄漏内存。
仅保留谓词指定的元素。
换句话说,删除所有元素 e
,以使 f(&e)
返回 false
。
此方法在原位运行,以原始顺序恰好一次访问每个元素,并保留保留元素的顺序。
Examples
let mut vec = vec![1, 2, 3, 4]; vec.retain(|&x| x % 2 == 0); assert_eq!(vec, [2, 4]);Run
由于按原始顺序仅对元素进行过一次访问,因此可以使用外部状态来确定要保留哪些元素。
let mut vec = vec![1, 2, 3, 4, 5]; let keep = [false, true, true, false, true]; let mut iter = keep.iter(); vec.retain(|_| *iter.next().unwrap()); assert_eq!(vec, [2, 3, 5]);Run
pub fn dedup_by_key<F, K>(&mut self, key: F) where
F: FnMut(&mut T) -> K,
K: PartialEq<K>,
1.16.0[src]
pub fn dedup_by_key<F, K>(&mut self, key: F) where
F: FnMut(&mut T) -> K,
K: PartialEq<K>,
1.16.0[src]移除 vector 中满足给定相等关系的所有连续元素,但第一个除外。
same_bucket
函数被传递给 vector 中的两个元素,并且必须确定这些元素比较是否相等。
元素以与它们在切片中的顺序相反的顺序传递,因此,如果 same_bucket(a, b)
返回 true
,则删除 a
。
如果对 vector 进行了排序,则将删除所有重复项。
Examples
let mut vec = vec!["foo", "bar", "Bar", "baz", "bar"]; vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b)); assert_eq!(vec, ["foo", "bar", "baz", "bar"]);Run
创建一个 draining 迭代器,该迭代器删除 vector 中的指定范围并产生删除的项。
当迭代器被丢弃时,该范围内的所有元素都将从 vector 中删除,即使迭代器未被完全消耗。
如果迭代器没有被丢弃 (例如,使用 mem::forget
),则不确定删除了多少个元素。
Panics
如果起点大于终点或终点大于 vector 的长度,则为 Panics。
Examples
let mut v = vec![1, 2, 3]; let u: Vec<_> = v.drain(1..).collect(); assert_eq!(v, &[1]); assert_eq!(u, &[2, 3]); // 全范围清除 vector v.drain(..); assert_eq!(v, &[]);Run
在适当位置调整 Vec
的大小,以使 len
等于 new_len
。
如果 new_len
大于 len
,则将 Vec
扩展该差值,并在每个额外的插槽中填充调用闭包 f
的结果。
f
的返回值将按照生成顺序返回到 Vec
。
如果 new_len
小于 len
,则将 Vec
截断。
此方法使用闭包在每次推送时创建新值。如果您希望给定值 Clone
,请使用 Vec::resize
。
如果要使用 Default
trait 生成值,则可以传递 Default::default
作为第二个参数。
Examples
let mut vec = vec![1, 2, 3]; vec.resize_with(5, Default::default); assert_eq!(vec, [1, 2, 3, 0, 0]); let mut vec = vec![]; let mut p = 1; vec.resize_with(4, || { p *= 2; p }); assert_eq!(vec, [2, 4, 8, 16]);Run
消耗并泄漏 Vec
,并向其中的内容返回变量引用, &'a mut [T]
.
请注意,类型 T
必须超过所选的生命周期 'a
。
如果类型仅具有静态引用,或者根本没有静态引用,则可以将其选择为 'static
。
该函数类似于 Box
上的 leak
函数,除了无法恢复泄漏的内存。
该函数主要用于在程序的剩余生命期内保留的数据。 丢弃返回的引用将导致内存泄漏。
Examples
简单用法:
let x = vec![1, 2, 3]; let static_ref: &'static mut [usize] = x.leak(); static_ref[0] += 1; assert_eq!(static_ref, &[2, 2, 3]);Run
以 MaybeUninit<T>
的切片形式返回 vector 的剩余备用容量。
返回的切片可用于用数据填充 vector (例如
(通过从文件读取) 来标记数据,然后再使用 set_len
方法将其标记为已初始化。
Examples
#![feature(vec_spare_capacity, maybe_uninit_extra)] // 分配足够大的 vector 以容纳 10 个元素。 let mut v = Vec::with_capacity(10); // 填写前 3 个元素。 let uninit = v.spare_capacity_mut(); uninit[0].write(0); uninit[1].write(1); uninit[2].write(2); // 将 vector 的前 3 个元素标记为已初始化。 unsafe { v.set_len(3); } assert_eq!(&v, &[0, 1, 2]);Run
返回 vector 内容作为 T
的切片,以及 vector 的剩余备用容量作为 MaybeUninit<T>
的切片。
返回的备用容量切片可用于在将数据标记为使用 set_len
方法初始化的数据之前 (例如,通过从文件读取) 将数据填充到 vector 中。
请注意,这是一个剧烈的 API,出于优化目的,应谨慎使用。
如果需要将数据附加到 Vec
,则可以根据实际需要使用 push
,extend
,extend_from_slice
,extend_from_within
,insert
,append
,resize
或 resize_with
。
Examples
#![feature(vec_split_at_spare, maybe_uninit_extra)] let mut v = vec![1, 1, 2]; // 保留足够大的空间来容纳 10 个元素。 v.reserve(10); let (init, uninit) = v.split_at_spare_mut(); let sum = init.iter().copied().sum::<u32>(); // 填写接下来的 4 个元素。 uninit[0].write(sum); uninit[1].write(sum * 2); uninit[2].write(sum * 3); uninit[3].write(sum * 4); // 将 vector 的 4 个元素标记为已初始化。 unsafe { let len = v.len(); v.set_len(len + 4); } assert_eq!(&v, &[1, 1, 2, 4, 8, 12, 16]);Run
在适当位置调整 Vec
的大小,以使 len
等于 new_len
。
如果 new_len
大于 len
,则 Vec
会扩展此差值,每个额外的插槽都将用 value
填充。
如果 new_len
小于 len
,则将 Vec
截断。
为了能够克隆传递的值,此方法需要 T
实现 Clone
。
如果需要更大的灵活性 (或希望依靠 Default
而不是 Clone
),请使用 Vec::resize_with
。
Examples
let mut vec = vec!["hello"]; vec.resize(3, "world"); assert_eq!(vec, ["hello", "world", "world"]); let mut vec = vec![1, 2, 3, 4]; vec.resize(2, 0); assert_eq!(vec, [1, 2]);Run
将元素从 src
复制到 vector 的末尾。
Examples
let mut vec = vec![0, 1, 2, 3, 4]; vec.extend_from_within(2..); assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4]); vec.extend_from_within(..2); assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1]); vec.extend_from_within(4..8); assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1, 4, 2, 3, 4]);Run
pub fn splice<R, I>(
&mut self,
range: R,
replace_with: I
) -> Splice<'_, <I as IntoIterator>::IntoIter, A>ⓘ where
R: RangeBounds<usize>,
I: IntoIterator<Item = T>,
1.21.0[src]
pub fn splice<R, I>(
&mut self,
range: R,
replace_with: I
) -> Splice<'_, <I as IntoIterator>::IntoIter, A>ⓘ where
R: RangeBounds<usize>,
I: IntoIterator<Item = T>,
1.21.0[src]创建一个拼接迭代器,用给定的 replace_with
迭代器替换 vector 中的指定范围,并生成已删除的项。
replace_with
长度不必与 range
相同。
range
即使直到最后都没有使用迭代器,也将删除该变量。
如果 Splice
值泄漏,则未指定从 vector 中删除了多少个元素。
仅当 Splice
值丢弃时才使用输入迭代器 replace_with
。
如果满足以下条件,则为最佳选择:
- 尾部 (
range
之后的 vector 中的元素) 为空, - 或
replace_with
产生的元素少于或等于 ‘range’ 的长度 - 或其
size_hint()
的下界是正确的。
否则,将分配一个临时的 vector 并将尾部移动两次。
Panics
如果起点大于终点或终点大于 vector 的长度,则为 Panics。
Examples
let mut v = vec![1, 2, 3]; let new = [7, 8]; let u: Vec<_> = v.splice(..2, new).collect(); assert_eq!(v, &[7, 8, 3]); assert_eq!(u, &[1, 2]);Run
pub fn drain_filter<F>(&mut self, filter: F) -> DrainFilter<'_, T, F, A>ⓘNotable traits for DrainFilter<'_, T, F, A>impl<'_, T, F, A> Iterator for DrainFilter<'_, T, F, A> where
F: FnMut(&mut T) -> bool,
A: Allocator, type Item = T;
where
F: FnMut(&mut T) -> bool,
[src]🔬 This is a nightly-only experimental API. (drain_filter
#43244)
recently added
pub fn drain_filter<F>(&mut self, filter: F) -> DrainFilter<'_, T, F, A>ⓘNotable traits for DrainFilter<'_, T, F, A>impl<'_, T, F, A> Iterator for DrainFilter<'_, T, F, A> where
F: FnMut(&mut T) -> bool,
A: Allocator, type Item = T;
where
F: FnMut(&mut T) -> bool,
[src]impl<'_, T, F, A> Iterator for DrainFilter<'_, T, F, A> where
F: FnMut(&mut T) -> bool,
A: Allocator, type Item = T;
🔬 This is a nightly-only experimental API. (drain_filter
#43244)
recently added
创建一个迭代器,该迭代器使用闭包确定是否应删除元素。
如果闭包返回 true,那么将删除并屈服该元素。 如果闭包返回 false,则该元素将保留在 vector 中,并且不会由迭代器产生。
使用此方法等效于以下代码:
let mut i = 0; while i < vec.len() { if some_predicate(&mut vec[i]) { let val = vec.remove(i); // 您的代码在这里 } else { i += 1; } }Run
但是 drain_filter
更易于使用。
drain_filter
这样做还可以提高效率,因为它可以使数组的元素大量回移。
请注意,无论选择保留还是删除 drain_filter
,您都可以对过滤器闭包中的每个元素进行可变的。
Examples
将数组拆分为偶数和几率,重新使用原始分配:
#![feature(drain_filter)] let mut numbers = vec![1, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15]; let evens = numbers.drain_filter(|x| *x % 2 == 0).collect::<Vec<_>>(); let odds = numbers; assert_eq!(evens, vec![2, 4, 6, 8, 14]); assert_eq!(odds, vec![1, 3, 5, 9, 11, 13, 15]);Run
Methods from Deref<Target = [T]>
pub fn get<I>(&self, index: I) -> Option<&<I as SliceIndex<[T]>>::Output> where
I: SliceIndex<[T]>,
[src]
pub fn get<I>(&self, index: I) -> Option<&<I as SliceIndex<[T]>>::Output> where
I: SliceIndex<[T]>,
[src]pub fn get_mut<I>(
&mut self,
index: I
) -> Option<&mut <I as SliceIndex<[T]>>::Output> where
I: SliceIndex<[T]>,
[src]
pub fn get_mut<I>(
&mut self,
index: I
) -> Option<&mut <I as SliceIndex<[T]>>::Output> where
I: SliceIndex<[T]>,
[src]pub unsafe fn get_unchecked<I>(
&self,
index: I
) -> &<I as SliceIndex<[T]>>::Output where
I: SliceIndex<[T]>,
[src]
pub unsafe fn get_unchecked<I>(
&self,
index: I
) -> &<I as SliceIndex<[T]>>::Output where
I: SliceIndex<[T]>,
[src]返回对元素或子切片的引用,而不进行边界检查。
有关安全的选择,请参见 get
。
Safety
即使没有使用所得的引用,使用越界索引调用此方法也是 undefined behavior。
Examples
let x = &[1, 2, 4]; unsafe { assert_eq!(x.get_unchecked(1), &2); }Run
pub unsafe fn get_unchecked_mut<I>(
&mut self,
index: I
) -> &mut <I as SliceIndex<[T]>>::Output where
I: SliceIndex<[T]>,
[src]
pub unsafe fn get_unchecked_mut<I>(
&mut self,
index: I
) -> &mut <I as SliceIndex<[T]>>::Output where
I: SliceIndex<[T]>,
[src]返回元素或子切片的可变引用,而不进行边界检查。
有关安全的选择,请参见 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++ 中很常见。
返回长度为 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());Run
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];
[src]
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];
[src]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]);Run
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];
1.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];
1.31.0[src]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']);Run
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];
1.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];
1.31.0[src]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']]);Run
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];
[src]
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];
[src]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]);Run
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];
[src]
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];
[src]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]);Run
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];
[src]
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];
[src]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());Run
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];
1.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];
1.31.0[src]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]);Run
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];
1.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];
1.31.0[src]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']);Run
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];
1.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];
1.31.0[src]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);Run
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,
[src]
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,
[src]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
返回由与 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());Run
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,
1.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,
1.51.0[src]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());Run
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,
1.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,
1.51.0[src]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);Run
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,
[src]
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,
[src]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(&[]));Run
#[must_use = "returns the subslice without modifying the original"]pub fn strip_prefix<P>(&self, prefix: &P) -> Option<&[T]> where
T: PartialEq<T>,
P: SlicePattern<Item = T> + ?Sized,
1.51.0[src]
#[must_use = "returns the subslice without modifying the original"]pub fn strip_prefix<P>(&self, prefix: &P) -> Option<&[T]> where
T: PartialEq<T>,
P: SlicePattern<Item = T> + ?Sized,
1.51.0[src]返回带有删除的前缀的子切片。
如果切片以 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()));Run
#[must_use = "returns the subslice without modifying the original"]pub fn strip_suffix<P>(&self, suffix: &P) -> Option<&[T]> where
T: PartialEq<T>,
P: SlicePattern<Item = T> + ?Sized,
1.51.0[src]
#[must_use = "returns the subslice without modifying the original"]pub fn strip_suffix<P>(&self, suffix: &P) -> Option<&[T]> where
T: PartialEq<T>,
P: SlicePattern<Item = T> + ?Sized,
1.51.0[src]返回删除后缀的子分片。
如果切片以 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);Run
Binary 在排序后的切片中搜索给定的元素。
如果找到该值,则返回 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]);Run
Binary 使用比较器函数搜索排序后的切片。
比较器函数应实现与基础切片的排序顺序一致的顺序,并返回指示其参数是所需目标的 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, });Run
Binary 使用关键字提取函数搜索排序后的切片。
假定按关键字对切片进行排序,例如使用相同的关键字提取函数对 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
pub fn partition_at_index(
&mut self,
index: usize
) -> (&mut [T], &mut T, &mut [T]) where
T: Ord,
[src]👎 Deprecated since 1.49.0: use the select_nth_unstable() instead
pub fn partition_at_index(
&mut self,
index: usize
) -> (&mut [T], &mut T, &mut [T]) where
T: Ord,
[src]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,
[src]👎 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,
[src]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,
[src]👎 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,
[src]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]);Run
pub fn partition_dedup_by<F>(&mut self, same_bucket: F) -> (&mut [T], &mut [T]) where
F: FnMut(&mut T, &mut T) -> bool,
[src]
pub fn partition_dedup_by<F>(&mut self, same_bucket: F) -> (&mut [T], &mut [T]) where
F: FnMut(&mut T, &mut T) -> bool,
[src]将除第一个连续元素之外的所有元素移动到满足给定相等关系的切片的末尾。
返回两个切片。第一个不包含连续的重复元素。 第二个包含没有指定顺序的所有重复项。
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"]);Run
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>,
[src]
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>,
[src]将除了第一个连续元素之外的所有元素移动到解析为相同键的切片的末尾。
返回两个切片。第一个不包含连续的重复元素。 第二个包含没有指定顺序的所有重复项。
如果对切片进行排序,则第一个返回的切片不包含重复项。
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
相同。
如果 T
实现 Copy
,则使用 copy_from_slice
的性能可能更高。
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]);Run
Rust 强制只对一个特定作用域中的特定数据进行一个变量引用,而没有不可变引用。
因此,尝试在单个切片上使用 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]);Run
Rust 强制只对一个特定作用域中的特定数据进行一个变量引用,而没有不可变引用。
因此,尝试在单个切片上使用 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]);Run
pub fn copy_within<R>(&mut self, src: R, dest: usize) where
T: Copy,
R: RangeBounds<usize>,
1.37.0[src]
pub fn copy_within<R>(&mut self, src: R, dest: usize) where
T: Copy,
R: RangeBounds<usize>,
1.37.0[src]使用记忆膜将元素从切片的一部分复制到自身的另一部分。
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]);Run
Rust 强制要求特定作用域中的特定数据只能有一个可变引用。
因此,尝试在单个切片上使用 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); }Run
🔬 This is a nightly-only experimental API. (is_sorted
#53485)
new API
🔬 This is a nightly-only experimental API. (is_sorted
#53485)
new API
检查此切片的元素是否已排序。
也就是说,对于每个元素 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
🔬 This is a nightly-only experimental API. (is_sorted
#53485)
new API
🔬 This is a nightly-only experimental API. (is_sorted
#53485)
new API
检查此切片的元素是否使用给定的比较器函数进行排序。
该函数使用给定的 compare
函数来确定两个元素的顺序,而不是使用 PartialOrd::partial_cmp
。
除此之外,它等效于 is_sorted
。有关更多信息,请参见其文档。
🔬 This is a nightly-only experimental API. (is_sorted
#53485)
new API
🔬 This is a nightly-only experimental API. (is_sorted
#53485)
new API
根据给定的谓词返回分区点的索引 (第二个分区的第一个元素的索引)。
假定切片根据给定的谓词进行了分区。 这意味着谓词返回 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
检查两个片是否是 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;
[src]
pub fn escape_ascii(&self) -> EscapeAscii<'_>ⓘNotable traits for EscapeAscii<'a>impl<'a> Iterator for EscapeAscii<'a> type Item = u8;
[src]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
扩展将引用中的元素复制到 Vec 之前的实现。
此实现专用于切片迭代器,它使用 copy_from_slice
一次附加整个切片。
pub fn from(v: Vec<T, A>) -> Box<[T], A>ⓘ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>
[src]
pub fn from(v: Vec<T, A>) -> Box<[T], A>ⓘ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>
[src]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>
将 Vec<T>
转换为 BinaryHeap<T>
。
此转换发生在原地,并且具有 O(n) 时间复杂度。
将 VecDeque<T>
变成 Vec<T>
。
这永远不需要重新分配,但是如果循环缓冲区恰好不在分配开始时,则确实需要进行 O(n) 数据移动。
Examples
use std::collections::VecDeque; // 这是 *O*(1)。 let deque: VecDeque<_> = (1..5).collect(); let ptr = deque.as_slices().0.as_ptr(); let vec = Vec::from(deque); assert_eq!(vec, [1, 2, 3, 4]); assert_eq!(vec.as_ptr(), ptr); // 这一项需要重新整理数据。 let mut deque: VecDeque<_> = (1..5).collect(); deque.push_front(9); deque.push_front(8); let ptr = deque.as_slices().1.as_ptr(); let vec = Vec::from(deque); assert_eq!(vec, [8, 9, 1, 2, 3, 4]); assert_eq!(vec.as_ptr(), ptr);Run
根据 core::borrow::Borrow
实现的要求,vector 的哈希值与相应的 3 的哈希值相同。
#![feature(build_hasher_simple_hash_one)] use std::hash::BuildHasher; let b = std::collections::hash_map::RandomState::new(); let v: Vec<u8> = vec![0xa8, 0x3c, 0x09]; let s: &[u8] = &[0xa8, 0x3c, 0x09]; assert_eq!(b.hash_one(v), b.hash_one(s));Run
type Item = T
type Item = T
被迭代的元素的类型。
实现 vectors 的比较, lexicographically.
如果 Vec<T>
的大小与请求的数组的大小完全匹配,则以数组的形式获取 Vec<T>
的全部内容。
Examples
use std::convert::TryInto; assert_eq!(vec![1, 2, 3].try_into(), Ok([1, 2, 3])); assert_eq!(<Vec<i32>>::new().try_into(), Ok([]));Run
如果长度不匹配,则输入以 Err
返回:
use std::convert::TryInto; let r: Result<[i32; 4], _> = (0..10).collect::<Vec<_>>().try_into(); assert_eq!(r, Err(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]));Run
如果只需要获得 Vec<T>
的前缀就可以了,您可以先调用 .truncate(N)
。
use std::convert::TryInto; let mut v = String::from("hello world").into_bytes(); v.sort(); v.truncate(2); let [a, b]: [_; 2] = v.try_into().unwrap(); assert_eq!(a, b' '); assert_eq!(b, b'd');Run
通过将 Vec<u8>
附加到 vector 来实现写操作。
vector 将根据需要增长。
将格式化的字符串写入此 writer,返回遇到的任何错误。 Read more