Struct std::vec::Vec1.0.0[][src]

pub struct Vec<T, A = Global> where
    A: Allocator
{ /* fields omitted */ }
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 vec1 = vec![1, 2, 3];
vec1.push(4);
let vec2 = Vec::from([1, 2, 3, 4]);
assert_eq!(vec1, vec2);
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 中,请使用 getget_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::newvec![]Vec::with_capacity(0) 或通过在空 Vec 上调用 shrink_to_fit 来构造容量为 0 的 Vec,则它将不会分配内存。同样,如果将零大小的类型存储在 Vec 内,则不会为它们分配空间。 Note 在这种情况下,Vec 可能不会报告 0capacity。 当且仅当 mem::size_of::<T>() * capacity() > 0 时,Vec 才会分配。 一般来说,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_fitshrink_to

如果报告的容量足够,pushinsert 将永远不会 (重新) 分配。如果 len == capacity,则 pushinsert 将 (重新) 分配。也就是说,报告的容量是完全准确的,可以信赖。如果需要,它甚至可以用来手动释放 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 的内存清零,这可能不会实际发生,因为优化器不认为这是一个必须保留的副作用。 但是,有一种情况我们不会中断:使用 unsafe 代码写入多余的容量,然后增加长度以匹配,始终是有效的。

当前,Vec 不保证删除元素的顺序。 顺序过去已更改,并且可能会再次更改。

Implementations

创建一个新的空 Vec<T>

直到将元素压入 vector 为止,vector 才会分配。

Examples
let mut vec: Vec<i32> = Vec::new();
Run

创建一个具有指定容量的新的空 Vec<T>

vector 将能够准确地容纳 capacity 元素而无需重新分配。 如果 capacity 为 0,则不会分配 vector。

重要的是要注意,尽管返回的 vector 具有指定的 容量,但 vector 的长度为零。

有关长度和容量之间差异的说明,请参见 容量和重新分配

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
🔬 This is a nightly-only experimental API. (allocator_api #32838)

创建一个新的空 Vec<T, A>

直到将元素压入 vector 为止,vector 才会分配。

Examples
#![feature(allocator_api)]

use std::alloc::System;

let mut vec: Vec<i32, _> = Vec::new_in(System);
Run
🔬 This is a nightly-only experimental API. (allocator_api #32838)

使用提供的分配器构造具有指定容量的新的空 Vec<T, A>

vector 将能够准确地容纳 capacity 元素而无需重新分配。 如果 capacity 为 0,则不会分配 vector。

重要的是要注意,尽管返回的 vector 具有指定的 容量,但 vector 的长度为零。

有关长度和容量之间差异的说明,请参见 容量和重新分配

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
🔬 This is a nightly-only experimental API. (allocator_api #32838)

直接从另一个 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

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
🔬 This is a nightly-only experimental API. (allocator_api #32838)

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

返回 vector 可以保留而无需重新分配的元素数。

Examples
let vec: Vec<i32> = Vec::with_capacity(10);
assert_eq!(vec.capacity(), 10);
Run

为给定的 Vec<T> 至少保留 additional 个要插入的元素保留容量。 该集合可以保留更多空间,以避免频繁的重新分配。 调用 reserve 后,容量将大于或等于 self.len() + additional。 如果容量已经足够,则不执行任何操作。

Panics

如果新容量超过 isize::MAX 字节,就会出现 panics。

Examples
let mut vec = vec![1];
vec.reserve(10);
assert!(vec.capacity() >= 11);
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

尝试为给 Vec<T> 至少插入 additional 个元素保留容量。 该集合可以保留更多空间,以避免频繁的重新分配。 调用 try_reserve 后,容量将大于或等于 self.len() + additional。 如果容量已经足够,则不执行任何操作。

Errors

如果容量溢出,或者分配器报告失败,则返回错误。

Examples
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

尝试保留将最小 additional 元素插入给定 Vec<T> 的最小容量。 调用 try_reserve_exact 后,如果返回 Ok(()),则容量将大于或等于 self.len() + additional

如果容量已经足够,则不执行任何操作。

请注意,分配器可能会给集合提供比其请求更多的空间。 因此,不能依靠容量来精确地最小化。 如果预计将来会插入,则最好使用 reserve

Errors

如果容量溢出,或者分配器报告失败,则返回错误。

Examples
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

尽可能缩小 vector 的容量。

它将降低到尽可能接近的长度,但是分配器仍可以通知 vector,还有空间可以容纳更多元素。

Examples
let mut vec = Vec::with_capacity(10);
vec.extend([1, 2, 3]);
assert_eq!(vec.capacity(), 10);
vec.shrink_to_fit();
assert!(vec.capacity() >= 3);
Run

将 vector 的容量减小一个下限。

容量将至少保持与长度和提供的值一样大。

如果当前容量小于下限,则为无操作。

Examples
let mut vec = Vec::with_capacity(10);
vec.extend([1, 2, 3]);
assert_eq!(vec.capacity(), 10);
vec.shrink_to(4);
assert!(vec.capacity() >= 4);
vec.shrink_to(0);
assert!(vec.capacity() >= 3);
Run

将 vector 转换为 Box<[T]>

请注意,这将减少任何多余的容量。

Examples
let v = vec![1, 2, 3];

let slice = v.into_boxed_slice();
Run

任何多余的容量都将被删除:

let mut vec = Vec::with_capacity(10);
vec.extend([1, 2, 3]);

assert_eq!(vec.capacity(), 10);
let slice = vec.into_boxed_slice();
assert_eq!(slice.into_vec().capacity(), 3);
Run

缩短 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 的切片。

等效于 &s[..]

Examples
use std::io::{self, Write};
let buffer = vec![1, 2, 3, 5, 8];
io::sink().write(buffer.as_slice()).unwrap();
Run

提取整个 vector 的可变切片。

等效于 &mut s[..]

Examples
use std::io::{self, Read};
let mut buffer = vec![0; 3];
io::repeat(0b101).read_exact(buffer.as_mut_slice()).unwrap();
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
🔬 This is a nightly-only experimental API. (allocator_api #32838)

返回底层分配器的引用。

将 vector 的长度强制为 new_len

这是一个低级操作,不维护该类型的任何正常不变量。 通常,使用安全操作之一 (例如 truncateresizeextendclear) 来更改 vector 的长度。

Safety
  • new_len 必须小于或等于 capacity()
  • old_len..new_len 上的元素必须初始化。
Examples

当 vector 用作其他代码的缓冲区时,尤其是在 FFI 上,此方法很有用:

pub fn get_dictionary(&self) -> Option<Vec<u8>> {
    // 根据 FFI 方法的文档,32768 字节总是足够的。
    let mut dict = Vec::with_capacity(32_768);
    let mut dict_length = 0;
    // SAFETY: 当 `deflateGetDictionary` 返回 `Z_OK` 时,它认为:
    // 1. `dict_length` 元素已初始化。
    // 2.
    // `dict_length` <= 使 `set_len` 对调用安全的容量 (32_768)。
    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 来正确丢弃内容,因此不会泄漏内存。

从 vector 中删除一个元素并返回它。

删除的元素被 vector 的最后一个元素替换。

这不会保留顺序,而是 O(1)。 如果需要保留元素顺序,请改用 remove

Panics

如果 index 越界,就会出现 panics。

Examples
let mut v = vec!["foo", "bar", "baz", "qux"];

assert_eq!(v.swap_remove(1), "bar");
assert_eq!(v, ["foo", "qux", "baz"]);

assert_eq!(v.swap_remove(0), "foo");
assert_eq!(v, ["baz", "qux"]);
Run

在 vector 内的位置 index 处插入一个元素,并将其后的所有元素向右移动。

Panics

如果为 index > len,就会出现 panics。

Examples
let mut vec = vec![1, 2, 3];
vec.insert(1, 4);
assert_eq!(vec, [1, 4, 2, 3]);
vec.insert(4, 5);
assert_eq!(vec, [1, 4, 2, 3, 5]);
Run

删除并返回 vector 中位置 index 的元素,将其后的所有元素向左移动。

Note: 因为这会转移其余元素,所以它的最坏情况性能为 O(n)。 如果不需要保留元素的顺序,请改用 swap_remove

Panics

如果 index 越界,就会出现 panics。

Examples
let mut v = vec![1, 2, 3];
assert_eq!(v.remove(1), 2);
assert_eq!(v, [1, 3]);
Run

仅保留谓词指定的元素。

换句话说,删除所有元素 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
🔬 This is a nightly-only experimental API. (vec_retain_mut #90829)

仅保留由谓词指定的元素,并将一个可变引用传递给它。

换句话说,删除所有元素 e,使得 f(&mut e) 返回 false。 此方法在原位运行,以原始顺序恰好一次访问每个元素,并保留保留元素的顺序。

Examples
#![feature(vec_retain_mut)]

let mut vec = vec![1, 2, 3, 4];
vec.retain_mut(|x| if *x > 3 {
    false
} else {
    *x += 1;
    true
});
assert_eq!(vec, [2, 3, 4]);
Run

删除 vector 中除第一个连续元素之外的所有元素,这些元素解析为同一键。

如果对 vector 进行了排序,则将删除所有重复项。

Examples
let mut vec = vec![10, 20, 21, 30, 20];

vec.dedup_by_key(|i| *i / 10);

assert_eq!(vec, [10, 20, 30, 20]);
Run

移除 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

将元素追加到集合的后面。

Panics

如果新容量超过 isize::MAX 字节,就会出现 panics。

Examples
let mut vec = vec![1, 2];
vec.push(3);
assert_eq!(vec, [1, 2, 3]);
Run

从 vector 中删除最后一个元素并返回它; 如果它为空,则返回 None

Examples
let mut vec = vec![1, 2, 3];
assert_eq!(vec.pop(), Some(3));
assert_eq!(vec, [1, 2]);
Run

other 的所有元素移到 Self,将 other 留空。

Panics

如果 vector 中的元素数量溢出 usize,就会出现 panics。

Examples
let mut vec = vec![1, 2, 3];
let mut vec2 = vec![4, 5, 6];
vec.append(&mut vec2);
assert_eq!(vec, [1, 2, 3, 4, 5, 6]);
assert_eq!(vec2, []);
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

清除 vector,删除所有值。

请注意,此方法对 vector 的已分配容量没有影响。

Examples
let mut v = vec![1, 2, 3];

v.clear();

assert!(v.is_empty());
Run

返回 vector 中的元素数,也称为 ‘length’。

Examples
let a = vec![1, 2, 3];
assert_eq!(a.len(), 3);
Run

如果 vector 不包含任何元素,则返回 true

Examples
let mut v = Vec::new();
assert!(v.is_empty());

v.push(1);
assert!(!v.is_empty());
Run

在给定的索引处将集合拆分为两个。

返回一个新分配的 vector,其中包含 [at, len) 范围内的元素。 调用之后,将保留原始 vector,其中包含元素 [0, at),而先前的容量不变。

Panics

如果为 at > len,就会出现 panics。

Examples
let mut vec = vec![1, 2, 3];
let vec2 = vec.split_off(1);
assert_eq!(vec, [1]);
assert_eq!(vec2, [2, 3]);
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

从 Rust 1.57 开始,此方法不会重新分配或收缩 Vec,因此泄漏的分配可能包括不属于返回切片的未使用的容量。

该函数主要用于在程序的剩余生命期内保留的数据。丢弃返回的引用将导致内存泄漏。

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
🔬 This is a nightly-only experimental API. (vec_spare_capacity #75017)

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
🔬 This is a nightly-only experimental API. (vec_split_at_spare #81944)

返回 vector 内容作为 T 的切片,以及 vector 的剩余备用容量作为 MaybeUninit<T> 的切片。

返回的备用容量切片可用于在将数据标记为使用 set_len 方法初始化的数据之前 (例如,通过从文件读取) 将数据填充到 vector 中。

请注意,这是一个剧烈的 API,出于优化目的,应谨慎使用。 如果需要将数据追加到 Vec,则可以根据实际需要使用 pushextendextend_from_sliceextend_from_withininsertappendresizeresize_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。 如果您只需要调整到更小的尺寸,请使用 Vec::truncate

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

克隆并将切片中的所有元素追加到 Vec

遍历切片 other,克隆每个元素,然后将其追加到此 Vecother vector 按顺序遍历。

请注意,此函数与 extend 相同,只不过它专门用于切片。

如果并且当 Rust 得到专门化时,此函数可能会被弃用 (但仍然可用)。

Examples
let mut vec = vec![1];
vec.extend_from_slice(&[2, 3, 4]);
assert_eq!(vec, [1, 2, 3, 4]);
Run

将元素从 src 复制到 vector 的末尾。

Panics

如果起点大于终点或终点大于 vector 的长度,就会出现 panics。

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

根据 PartialEq trait 的实现,删除 vector 中连续的重复元素。

如果对 vector 进行了排序,则将删除所有重复项。

Examples
let mut vec = vec![1, 2, 2, 3, 2];

vec.dedup();

assert_eq!(vec, [1, 2, 3, 2]);
Run

创建一个拼接迭代器,用给定的 replace_with 迭代器替换 vector 中的指定范围,并生成已删除的项。

replace_with 不需要与 range 的长度相同。

即使直到最后才消耗迭代器,range 也会被删除。

如果 Splice 值泄漏,则未指定从 vector 中删除了多少个元素。

输入迭代器 replace_with 只有在 Splice 值被丢弃时才会被消耗。

如果满足以下条件,则为最佳选择:

  • 尾部 (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
🔬 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]>

返回切片中的元素数。

Examples
let a = [1, 2, 3];
assert_eq!(a.len(), 3);
Run

如果切片的长度为 0,则返回 true

Examples
let a = [1, 2, 3];
assert!(!a.is_empty());
Run

返回切片的第一个元素; 如果为空,则返回 None

Examples
let v = [10, 40, 30];
assert_eq!(Some(&10), v.first());

let w: &[i32] = &[];
assert_eq!(None, w.first());
Run

返回指向切片第一个元素的可变指针,如果为空则返回 None

Examples
let x = &mut [0, 1, 2];

if let Some(first) = x.first_mut() {
    *first = 5;
}
assert_eq!(x, &[5, 1, 2]);
Run

返回切片的第一个元素和所有其他元素,如果为空,则返回 None

Examples
let x = &[0, 1, 2];

if let Some((first, elements)) = x.split_first() {
    assert_eq!(first, &0);
    assert_eq!(elements, &[1, 2]);
}
Run

返回切片的第一个元素和所有其他元素,如果为空,则返回 None

Examples
let x = &mut [0, 1, 2];

if let Some((first, elements)) = x.split_first_mut() {
    *first = 3;
    elements[0] = 4;
    elements[1] = 5;
}
assert_eq!(x, &[3, 4, 5]);
Run

返回切片的最后一个元素和所有其他元素,如果为空,则返回 None

Examples
let x = &[0, 1, 2];

if let Some((last, elements)) = x.split_last() {
    assert_eq!(last, &2);
    assert_eq!(elements, &[0, 1]);
}
Run

返回切片的最后一个元素和所有其他元素,如果为空,则返回 None

Examples
let x = &mut [0, 1, 2];

if let Some((last, elements)) = x.split_last_mut() {
    *last = 3;
    elements[0] = 4;
    elements[1] = 5;
}
assert_eq!(x, &[4, 5, 3]);
Run

返回切片的最后一个元素; 如果为空,则返回 None

Examples
let v = [10, 40, 30];
assert_eq!(Some(&30), v.last());

let w: &[i32] = &[];
assert_eq!(None, w.last());
Run

返回指向切片中最后一个项的可变指针。

Examples
let x = &mut [0, 1, 2];

if let Some(last) = x.last_mut() {
    *last = 10;
}
assert_eq!(x, &[0, 1, 10]);
Run

根据索引的类型返回对元素或子切片的引用。

  • 如果给定位置,则返回该位置上的元素的引用,如果越界则返回 None

  • 如果给定范围,则返回对应于该范围的子切片; 如果越界,则返回 None

Examples
let v = [10, 40, 30];
assert_eq!(Some(&40), v.get(1));
assert_eq!(Some(&[10, 40][..]), v.get(0..2));
assert_eq!(None, v.get(3));
assert_eq!(None, v.get(0..4));
Run

根据索引的类型 (请参见 get) 或 None (如果索引越界),对元素或子切片返回可变引用。

Examples
let x = &mut [0, 1, 2];

if let Some(elem) = x.get_mut(1) {
    *elem = 42;
}
assert_eq!(x, &[0, 42, 2]);
Run

返回对元素或子切片的引用,而不进行边界检查。

有关安全的选择,请参见 get

Safety

即使没有使用所得的引用,使用越界索引调用此方法也是 undefined behavior

Examples
let x = &[1, 2, 4];

unsafe {
    assert_eq!(x.get_unchecked(1), &2);
}
Run

返回元素或子切片的可变引用,而不进行边界检查。

有关安全的选择,请参见 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

返回指向切片缓冲区的不安全可变指针。

调用者必须确保切片比该函数返回的指针有效,否则它将最终指向垃圾。

修改此切片引用的容器可能会导致重新分配其缓冲区,这也将使指向它的任何指针无效。

Examples
let x = &mut [1, 2, 4];
let x_ptr = x.as_mut_ptr();

unsafe {
    for i in 0..x.len() {
        *x_ptr.add(i) += 2;
    }
}
assert_eq!(x, &[3, 4, 6]);
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++ 中很常见。

在切片中交换两个元素。

Arguments
  • a - 第一个元素的索引
  • b - 第二个元素的索引
Panics

如果 ab 越界,就会出现 panics。

Examples
let mut v = ["a", "b", "c", "d", "e"];
v.swap(2, 4);
assert!(v == ["a", "b", "e", "d", "c"]);
Run
🔬 This is a nightly-only experimental API. (slice_swap_unchecked #88539)

在不做边界检查的情况下交换切片中的两个元素。

有关安全的替代方案,请参见 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

适当地反转切片中元素的顺序。

Examples
let mut v = [1, 2, 3];
v.reverse();
assert!(v == [3, 2, 1]);
Run

返回切片上的迭代器。

Examples
let x = &[1, 2, 4];
let mut iterator = x.iter();

assert_eq!(iterator.next(), Some(&1));
assert_eq!(iterator.next(), Some(&2));
assert_eq!(iterator.next(), Some(&4));
assert_eq!(iterator.next(), None);
Run

返回允许修改每个值的迭代器。

Examples
let x = &mut [1, 2, 4];
for elem in x.iter_mut() {
    *elem += 2;
}
assert_eq!(x, &[3, 4, 6]);
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());
Run

从切片的开头开始,一次返回对切片的 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

从切片的开头开始,一次返回对切片的 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

从切片的开头开始,一次返回对切片的 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
🔬 This is a nightly-only experimental API. (slice_as_chunks #74985)

假设没有余数,将切片拆分为 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
🔬 This is a nightly-only experimental API. (slice_as_chunks #74985)

从切片的开头开始,将切片分成 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
🔬 This is a nightly-only experimental API. (slice_as_chunks #74985)

从切片的末尾开始,将切片分成 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
🔬 This is a nightly-only experimental API. (array_chunks #74985)

从切片的开头开始,一次返回对切片的 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
🔬 This is a nightly-only experimental API. (slice_as_chunks #74985)

假设没有余数,将切片拆分为 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
🔬 This is a nightly-only experimental API. (slice_as_chunks #74985)

从切片的开头开始,将切片分成 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
🔬 This is a nightly-only experimental API. (slice_as_chunks #74985)

从切片的末尾开始,将切片分成 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
🔬 This is a nightly-only experimental API. (array_chunks #74985)

从切片的开头开始,一次返回对切片的 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
🔬 This is a nightly-only experimental API. (array_windows #75027)

从切片的开头开始,在切片的 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

从切片的末尾开始,一次返回对切片的 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

从切片的末尾开始,一次返回对切片的 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

从切片的末尾开始,一次返回对切片的 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
🔬 This is a nightly-only experimental API. (slice_group_by #80552)

返回在切片上使用迭代器生成迭代器的迭代器,这些谓词使用谓词将它们分隔开。

谓词在紧随其后的两个元素上调用,这意味着谓词在 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
🔬 This is a nightly-only experimental API. (slice_group_by #80552)

返回在切片上使用谓词将其分离的迭代器,以生成不重叠的可变元素游程。

谓词在紧随其后的两个元素上调用,这意味着谓词在 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
🔬 This is a nightly-only experimental API. (slice_split_at_unchecked #76014)

new API

在索引处将一个切片分为两个,而无需进行边界检查。

第一个将包含 [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
🔬 This is a nightly-only experimental API. (slice_split_at_unchecked #76014)

new API

在索引处将一个可变切片分为两个,而无需进行边界检查。

第一个将包含 [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
🔬 This is a nightly-only experimental API. (split_array #90091)

new API

将一个切片分成一个数组和一个索引处的剩余切片。

该数组将包含来自 [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
🔬 This is a nightly-only experimental API. (split_array #90091)

new API

将一个可变切片分成一个数组和一个索引处的剩余切片。

该数组将包含来自 [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

返回由与 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

返回由匹配 pred 的元素分隔的可变子切片上的迭代器。 匹配的元素不包含在子切片中。

Examples
let mut v = [10, 40, 30, 20, 60, 50];

for group in v.split_mut(|num| *num % 3 == 0) {
    group[0] = 1;
}
assert_eq!(v, [1, 40, 30, 1, 60, 1]);
Run

返回由与 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

返回由匹配 pred 的元素分隔的可变子切片上的迭代器。 匹配的元素作为终止符包含在先前的子切片中。

Examples
let mut v = [10, 40, 30, 20, 60, 50];

for group in v.split_inclusive_mut(|num| *num % 3 == 0) {
    let terminator_idx = group.len()-1;
    group[terminator_idx] = 1;
}
assert_eq!(v, [10, 40, 1, 20, 1, 1]);
Run

在子切片上返回一个迭代器,该迭代器由与 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

返回在可变子切片上的迭代器,该子切片由与 pred 匹配的元素分隔,从切片的末尾开始并向后工作。 匹配的元素不包含在子切片中。

Examples
let mut v = [100, 400, 300, 200, 600, 500];

let mut count = 0;
for group in v.rsplit_mut(|num| *num % 3 == 0) {
    count += 1;
    group[0] = count;
}
assert_eq!(v, [3, 400, 300, 2, 600, 1]);
Run

在子切片上返回一个迭代器,该子切片由与 pred 匹配的元素分隔,限于最多返回 n 项。 匹配的元素不包含在子切片中。

返回的最后一个元素 (如果有) 将包含切片的其余部分。

Examples

按 3 的整数倍数 (即 [10, 40][20, 60, 50]) 打印一次切片分割:

let v = [10, 40, 30, 20, 60, 50];

for group in v.splitn(2, |num| *num % 3 == 0) {
    println!("{:?}", group);
}
Run

在子切片上返回一个迭代器,该子切片由与 pred 匹配的元素分隔,限于最多返回 n 项。 匹配的元素不包含在子切片中。

返回的最后一个元素 (如果有) 将包含切片的其余部分。

Examples
let mut v = [10, 40, 30, 20, 60, 50];

for group in v.splitn_mut(2, |num| *num % 3 == 0) {
    group[0] = 1;
}
assert_eq!(v, [1, 40, 30, 1, 60, 50]);
Run

在子切片上返回一个迭代器,该子切片由与 pred 匹配的元素分隔,最多只能返回 n 项。 该操作从切片的末尾开始并向后工作。 匹配的元素不包含在子切片中。

返回的最后一个元素 (如果有) 将包含切片的其余部分。

Examples

从末尾开始,将切片拆分打印一次,并被 3 整除的数字 (即 [50][10, 40, 30, 20]) :

let v = [10, 40, 30, 20, 60, 50];

for group in v.rsplitn(2, |num| *num % 3 == 0) {
    println!("{:?}", group);
}
Run

在子切片上返回一个迭代器,该子切片由与 pred 匹配的元素分隔,最多只能返回 n 项。 该操作从切片的末尾开始并向后工作。 匹配的元素不包含在子切片中。

返回的最后一个元素 (如果有) 将包含切片的其余部分。

Examples
let mut s = [10, 40, 30, 20, 60, 50];

for group in s.rsplitn_mut(2, |num| *num % 3 == 0) {
    group[0] = 1;
}
assert_eq!(s, [1, 40, 30, 20, 60, 1]);
Run

如果切片包含具有给定值的元素,则返回 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

返回带有删除的前缀的子切片。

如果切片以 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

返回删除后缀的子分片。

如果切片以 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_bybinary_search_by_keypartition_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 使用比较器函数搜索排序后的切片。

comparator 函数应该实现一个与底层切片的排序顺序一致的顺序,返回一个顺序代码,并指示其参数期望的目标是 LessEqual 还是 Greater

如果找到该值,则返回 Result::Ok,其中包含匹配元素的索引。如果有多个匹配项,则可以返回任何一个匹配项。 索引的选择是确定的,但在 Rust 的未来版本中可能会发生变化。 如果找不到该值,则返回 Result::Err,其中包含在保留排序顺序的同时可以在其中插入匹配元素的索引。

另请参见 binary_searchbinary_search_by_keypartition_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_searchbinary_search_bypartition_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, bc),那么它就是一个总体顺序

  • 完全和反对称的: a < ba == ba > b 之一正确,并且
  • 可传递的,a < bb < 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

🔬 This is a nightly-only experimental API. (slice_partition_at_index #55300)

重新排序切片,以使 index 处的元素处于其最终排序位置。

👎 Deprecated since 1.49.0:

use select_nth_unstable_by() instead

🔬 This is a nightly-only experimental API. (slice_partition_at_index #55300)

使用比较器函数对切片进行重新排序,以使 index 处的元素处于其最终排序位置。

👎 Deprecated since 1.49.0:

use the select_nth_unstable_by_key() instead

🔬 This is a nightly-only experimental API. (slice_partition_at_index #55300)

使用键提取函数对切片进行重新排序,以使 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
🔬 This is a nightly-only experimental API. (slice_partition_dedup #54279)

根据 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
🔬 This is a nightly-only experimental API. (slice_partition_dedup #54279)

将除第一个连续元素之外的所有元素移动到满足给定相等关系的切片的末尾。

返回两个切片。第一个不包含连续的重复元素。 第二个包含没有指定顺序的所有重复项。

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
🔬 This is a nightly-only experimental API. (slice_partition_dedup #54279)

将除了第一个连续元素之外的所有元素移动到解析为相同键的切片的末尾。

返回两个切片。第一个不包含连续的重复元素。 第二个包含没有指定顺序的所有重复项。

如果对切片进行排序,则第一个返回的切片不包含重复项。

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

通过克隆 value,用元素填充 self

Examples
let mut buf = vec![0; 10];
buf.fill(1);
assert_eq!(buf, vec![1; 10]);
Run

用重复调用闭包返回的元素填充 self

此方法使用闭包创建新值。如果您希望给定值 Clone,请使用 fill。 如果要使用 Default trait 生成值,则可以传递 Default::default 作为参数。

Examples
let mut buf = vec![1; 10];
buf.fill_with(Default::default);
assert_eq!(buf, vec![0; 10]);
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]);
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

使用记忆膜将元素从切片的一部分复制到自身的另一部分。

srcself 内要复制的范围。 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

检查此切片的元素是否已排序。

也就是说,对于每个元素 a 及其后续元素 ba <= 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

检查此切片的元素是否使用给定的比较器函数进行排序。

该函数使用给定的 compare 函数来确定两个元素的顺序,而不是使用 PartialOrd::partial_cmp。 除此之外,它等效于 is_sorted。有关更多信息,请参见其文档。

🔬 This is a nightly-only experimental API. (is_sorted #53485)

new API

检查此切片的元素是否使用给定的键提取函数进行排序。

该函数将直接比较由 f 确定的元素的键,而不是直接比较切片的元素。 除此之外,它等效于 is_sorted。有关更多信息,请参见其文档。

Examples
#![feature(is_sorted)]

assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
Run

根据给定的谓词返回分区点的索引 (第二个分区的第一个元素的索引)。

假定切片根据给定的谓词进行了分区。 这意味着谓词返回 true 的所有元素都在切片的开头,谓词返回 false 的所有元素都在切片的结尾。

例如,[7, 15, 3, 5, 4, 12, 6] 在谓词 x % 2 != 0 下进行了分区 (所有的奇数都在开头,所有的偶数都在结尾)。

如果未对该切片进行分区,则返回的结果是不确定的且无意义的,因为此方法执行一种二进制搜索。

另请参见 binary_searchbinary_search_bybinary_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 范围内。

检查两个片是否是 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

🔬 This is a nightly-only experimental API. (inherent_ascii_escape #77174)

返回一个迭代器,该迭代器产生此转义版本的一个 ASCII 字符串,将其视为一个 ASCII 字符串。

Examples
#![feature(inherent_ascii_escape)]

let s = b"0\t\r\n'\"\\\x9d";
let escaped = s.escape_ascii().to_string();
assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d");
Run

对切片进行排序。

这种排序是稳定的 (即,不对相等的元素重新排序),并且 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, bc),那么它就是一个总体顺序

  • 完全和反对称的: a < ba == ba > b 之一正确,并且
  • 可传递的,a < bb < 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

self 复制到新的 Vec 中。

Examples
let s = [10, 40, 30];
let x = s.to_vec();
// 在此,`s` 和 `x` 可以独立修改。
Run
🔬 This is a nightly-only experimental API. (allocator_api #32838)

使用分配器将 self 复制到新的 Vec 中。

Examples
#![feature(allocator_api)]

use std::alloc::System;

let s = [10, 40, 30];
let x = s.to_vec_in(System);
// 在此,`s` 和 `x` 可以独立修改。
Run

通过重复切片 n 次来创建 vector。

Panics

如果容量溢出,此函数将为 panic。

Examples

基本用法:

assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);
Run

溢出时为 panic:

// 这将在运行时 panic
b"0123456789abcdef".repeat(usize::MAX);
Run

T 的切片展平为单个值 Self::Output

Examples
assert_eq!(["hello", "world"].concat(), "helloworld");
assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
Run

T 的切片展平为单个值 Self::Output,并在每个值之间放置一个给定的分隔符。

Examples
assert_eq!(["hello", "world"].join(" "), "hello world");
assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);
Run
👎 Deprecated since 1.3.0:

renamed to join

T 的切片展平为单个值 Self::Output,并在每个值之间放置一个给定的分隔符。

Examples
assert_eq!(["hello", "world"].connect(" "), "hello world");
assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
Run

返回一个 vector,其中包含此切片的副本,其中每个字节都映射到其等效的 ASCII 大写字母。

ASCII 字母 ‘a’ 到 ‘z’ 映射到 ‘A’ 到 ‘Z’,但是非 ASCII 字母不变。

要就地将值大写,请使用 make_ascii_uppercase

返回一个 vector,其中包含该切片的副本,其中每个字节均映射为其等效的 ASCII 小写字母。

ASCII 字母 ‘A’ 到 ‘Z’ 映射到 ‘a’ 到 ‘z’,但是非 ASCII 字母不变。

要就地小写该值,请使用 make_ascii_lowercase

Trait Implementations

执行转换。

执行转换。

执行转换。

执行转换。

从拥有的值中一成不变地借用。 Read more

从拥有的值中借用。 Read more

返回值的副本。 Read more

source 执行复制分配。 Read more

使用给定的格式化程序格式化该值。 Read more

创建一个空的 Vec<T>

解引用后的结果类型。

解引用值。

可变地解引用该值。

执行此类型的析构函数。 Read more

扩展将引用中的元素复制到 Vec 之前的实现。

此实现专用于切片迭代器,它使用 copy_from_slice 一次追加整个切片。

使用迭代器的内容扩展集合。 Read more

🔬 This is a nightly-only experimental API. (extend_one #72631)

用一个元素扩展一个集合。

🔬 This is a nightly-only experimental API. (extend_one #72631)

在集合中为给定数量的附加元素保留容量。 Read more

使用迭代器的内容扩展集合。 Read more

🔬 This is a nightly-only experimental API. (extend_one #72631)

用一个元素扩展一个集合。

🔬 This is a nightly-only experimental API. (extend_one #72631)

在集合中为给定数量的附加元素保留容量。 Read more

分配一个 Vec<T> 并通过克隆 s 的项来填充它。

Examples
assert_eq!(Vec::from(&[1, 2, 3][..]), vec![1, 2, 3]);
Run

分配一个 Vec<T> 并通过克隆 s 的项来填充它。

Examples
assert_eq!(Vec::from(&mut [1, 2, 3][..]), vec![1, 2, 3]);
Run

分配一个 Vec<u8> 并用 UTF-8 字符串填充它。

Examples
assert_eq!(Vec::from("123"), vec![b'1', b'2', b'3']);
Run

Vec 的引用创建 CowBorrowed 变体。

此转换不会分配或克隆数据。

执行转换。

BinaryHeap<T> 转换为 Vec<T>

这种转换不需要数据移动或分配,并且具有恒定的时间复杂度。

通过转移现有堆分配的所有权,将 boxed 切片转换为 vector。

Examples
let b: Box<[i32]> = vec![1, 2, 3].into_boxed_slice();
assert_eq!(Vec::from(b), vec![1, 2, 3]);
Run

CString 转换为 Vec<u8>

转换消耗 CString,并删除终止的 NUL 字节。

将写时克隆切片转换为 vector。

如果 s 已经拥有 Vec<T>,则直接返回。 如果 s 是借用了一个切片,将通过克隆 s 的项来分配和填充一个新的 Vec

Examples
let o: Cow<[i32]> = Cow::Owned(vec![1, 2, 3]);
let b: Cow<[i32]> = Cow::Borrowed(&[1, 2, 3]);
assert_eq!(Vec::from(o), Vec::from(b));
Run

将给定的 String 转换为包含 u8 类型值的 vector Vec

Examples

基本用法:

let s1 = String::from("hello world");
let v1 = Vec::from(s1);

for b in v1 {
    println!("{}", b);
}
Run

Vec<NonZeroU8> 转换为 CString,无需复制或检查内部空字节。

Vec<T> 变成 VecDeque<T>

这样可以避免在可能的情况下进行重新分配,但是这样做的条件很严格,并且随时可能更改,因此除非 Vec<T> 来自 From<VecDeque<T>> 并且尚未重新分配,否则不应依赖它。

将 vector 转换为 boxed。

如果 v 有多余的容量,它的项将被移动到新分配的缓冲区中,缓冲区的容量恰好是正确的。

Examples
assert_eq!(Box::from(vec![1, 2, 3]), vec![1, 2, 3].into_boxed_slice());
Run

Vec<T> 转换为 BinaryHeap<T>

此转换发生在原地,并且具有 O(n) 时间复杂度。

分配一个引用计数的切片,并将 v 的项移入其中。

Example
let unique: Vec<i32> = vec![1, 2, 3];
let shared: Arc<[i32]> = Arc::from(unique);
assert_eq!(&[1, 2, 3], &shared[..]);
Run

分配一个引用计数的切片,并将 v 的项移入其中。

Example
let original: Box<Vec<i32>> = Box::new(vec![1, 2, 3]);
let shared: Rc<Vec<i32>> = Rc::from(original);
assert_eq!(vec![1, 2, 3], *shared);
Run

从拥有所有权的 Vec 实例创建 CowOwned 变体。

此转换不会分配或克隆数据。

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

从迭代器创建一个值。 Read more

根据 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

将该值输入给定的 HasherRead more

将这种类型的切片送入给定的 Hasher 中。 Read more

索引后返回的类型。

执行索引 (container[index]) 操作。 Read more

执行可变索引 (container[index]) 操作。 Read more

创建一个消耗迭代器,即一个将每个值移出 vector (从开始到结束) 的迭代器。 调用此后不能使用 vector。

Examples
let v = vec!["a".to_string(), "b".to_string()];
for s in v.into_iter() {
    // s 具有字符串类型,而不是 &String
    println!("{}", s);
}
Run

被迭代的元素的类型。

我们将其变成哪种迭代器?

被迭代的元素的类型。

我们将其变成哪种迭代器?

从一个值创建一个迭代器。 Read more

被迭代的元素的类型。

我们将其变成哪种迭代器?

从一个值创建一个迭代器。 Read more

实现 vectors、字典顺序 的排序。

此方法返回 selfother 之间的 OrderingRead more

比较并返回两个值中的最大值。 Read more

比较并返回两个值中的最小值。 Read more

将值限制在某个时间间隔内。 Read more

此方法测试 selfother 值是否相等,并由 == 使用。 Read more

此方法测试 !=

此方法测试 selfother 值是否相等,并由 == 使用。 Read more

此方法测试 !=

此方法测试 selfother 值是否相等,并由 == 使用。 Read more

此方法测试 !=

此方法测试 selfother 值是否相等,并由 == 使用。 Read more

此方法测试 !=

此方法测试 selfother 值是否相等,并由 == 使用。 Read more

此方法测试 !=

此方法测试 selfother 值是否相等,并由 == 使用。 Read more

此方法测试 !=

此方法测试 selfother 值是否相等,并由 == 使用。 Read more

此方法测试 !=

此方法测试 selfother 值是否相等,并由 == 使用。 Read more

此方法测试 !=

此方法测试 selfother 值是否相等,并由 == 使用。 Read more

此方法测试 !=

此方法测试 selfother 值是否相等,并由 == 使用。 Read more

此方法测试 !=

此方法测试 selfother 值是否相等,并由 == 使用。 Read more

此方法测试 !=

实现 vectors、字典顺序 的比较。

如果存在,则此方法返回 selfother 值之间的顺序。 Read more

此方法测试的内容少于 (对于 selfother),并且由 < 操作员使用。 Read more

此方法测试小于或等于 (对于 selfother),并且由 <= 运算符使用。 Read more

此方法测试大于 (对于 selfother),并且由 > 操作员使用。 Read more

此方法测试是否大于或等于 (对于 selfother),并且由 >= 运算符使用。 Read more

如果 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

类似于 write,不同之处在于它是从缓冲区切片中写入数据的。 Read more

🔬 This is a nightly-only experimental API. (can_vector #69941)

确定此 Writer 是否具有有效的 write_vectored 实现。 Read more

尝试将整个缓冲区写入此 writer。 Read more

刷新此输出流,确保所有中间缓冲的内容均到达其目的地。 Read more

🔬 This is a nightly-only experimental API. (write_all_vectored #70436)

尝试将多个缓冲区写入此 writer。 Read more

将格式化的字符串写入此 writer,返回遇到的任何错误。 Read more

为这个 Write 实例创建一个 “by reference” 适配器。 Read more

Auto Trait Implementations

Blanket Implementations

获取 selfTypeIdRead more

从拥有的值中一成不变地借用。 Read more

从拥有的值中借用。 Read more

执行转换。

执行转换。

获得所有权后的结果类型。

从借用的数据创建拥有的数据,通常是通过克隆。 Read more

🔬 This is a nightly-only experimental API. (toowned_clone_into #41263)

recently added

使用借来的数据来替换拥有的数据,通常是通过克隆。 Read more

发生转换错误时返回的类型。

执行转换。

发生转换错误时返回的类型。

执行转换。