Struct alloc::vec::Vec1.0.0[−][src]

pub struct Vec<T, A: Allocator = Global> { /* 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 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 为止,vector 才会分配。

Examples

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

创建一个具有指定容量的新的空 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
🔬 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 具有指定的 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
🔬 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
🔬 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

尝试保留将最小 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

尽可能缩小 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
🔬 This is a nightly-only experimental API. (shrink_to #56431)

new API

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

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

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

Examples

#![feature(shrink_to)]
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。

这是一个维操作,不保留该类型的任何普通不变式。 通常,使用安全操作之一 (例如 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 来正确丢弃内容,因此不会泄漏内存。

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

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

这不会保留排序,但是是 O(1)。

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 的元素,将其后的所有元素向左移动。

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

删除 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。

该函数类似于 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
🔬 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,则可以根据实际需要使用 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

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

遍历切片 other,克隆每个元素,然后将其附加到此 Vec。 other 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 的末尾。

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 中删除了多少个元素。

仅当 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
🔬 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

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 的引用创建 Cow 的 Borrowed 变体。

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

执行转换。

将 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

将写时克隆切片转换为 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

将 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) 时间复杂度。

将 Vec<T> 变成 VecDeque<T>。

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

分配一个引用计数的切片,并将 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

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

Example

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

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

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

将 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

将该值输入给定的 Hasher。 Read 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 的排序, lexicographically.

此方法返回 self 和 other 之间的 Ordering。 Read more

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

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

将值限制为一定的时间间隔。 Read more

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

此方法测试 !=。

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

此方法测试 !=。

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

此方法测试 !=。

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

此方法测试 !=。

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

此方法测试 !=。

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

此方法测试 !=。

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

此方法测试 !=。

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

此方法测试 !=。

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

此方法测试 !=。

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

此方法测试 !=。

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

此方法测试 !=。

实现 vectors 的比较, lexicographically.

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

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

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

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

此方法测试是否大于或等于 (对于 self 和 other),并且由 >= 运算符使用。 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

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

Auto Trait Implementations

Blanket Implementations

获取 self 的 TypeId。 Read more

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

从拥有的值中借用。 Read more

执行转换。

执行转换。

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

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

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

recently added

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

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

执行转换。

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

执行转换。