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 中,请使用 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 可能不会报告 capacity 为 0Vec 将仅在 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_fitshrink_to

push 如果报告的容量足够,则 insert 将永远不会 (重新) 分配。如果 len==capacitypushinsert 将 * (重新) 分配。也就是说,报告的容量是完全准确的,并且可以依赖。如果需要,它甚至可以用来手动释放 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

这是一个维操作,不保留该类型的任何普通不变式。 通常,使用安全操作之一 (例如 truncateresizeextendclear) 来更改 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,则可以根据实际需要使用 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

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 的末尾。

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 的引用创建 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

将写时克隆切片转换为 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 实例创建 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 的排序, lexicographically.

此方法返回 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 的比较, lexicographically.

如果存在,则此方法返回 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

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

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

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

执行转换。

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

执行转换。