Vector
Vector(动态数组)是一种连续的可增长数组类型,写成 Vec<T>,它是vector的缩写。
pub struct Vec<T, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global> {
buf: RawVec<T, A>,
len: usize,
}1.创建Vec
创建Vec有常用的方式
- 一种是使用关联函数
Vec::new() - 一种是使用
vec![]宏 - 也可以使用
vec::from()
1.1 Vec::new()
使用 Vec::new 创建动态数组是最 rust 的方式,它调用了 Vec 中的 new 关联函数,不过不可以给于初始值
let v: Vec<i32> = Vec::new();这里,v 被显式地声明了类型 Vec<i32>,这是因为 Rust 编译器无法从 Vec::new() 中得到任何关于类型的暗示信息,因此也无法推导出 v 的具体类型,但是当你向里面增加一个元素后,一切又不同了:
let mut v = Vec::new();
v.push(1);此时,v 就无需手动声明类型,因为编译器通过 v.push(1),推测出 v 中的元素类型是 i32,因此推导出 v 的类型是 Vec<i32>。
TIP
如果预先知道要存储的元素个数,可以使用 Vec::with_capacity(capacity) 创建动态数组,这样可以避免因为插入大量新数据导致频繁的内存分配和拷贝,提升性能
1.2 vec![]宏
vec![]宏创建vec就比较方便,因为它可以接收一个数组切片,用于初始化
let v = vec![11, 22, 33];
println!("{:#?}", v)
// [
// 11,
// 22,
// 33,
// ]1.3 vec::from()
vec::from()和vec![]类似,也是可以接收一个数组切片,用于初始化
let v = Vec::from([11, 22, 33]);
println!("{:#?}", v)
// [
// 11,
// 22,
// 33,
// ]2.更新Vec
向数组尾部添加元素,可以使用 push 方法:
let mut v = Vec::new();
v.push(1);与其它类型一样,必须将 v 声明为 mut 后,才能进行修改。
3.Vec与其元素共存亡
跟结构体一样,Vector 类型在超出作用域范围后,会被自动删除:
{
let v = vec![1, 2, 3];
// ...
} // <- v超出作用域并在此处被删除当 Vector 被删除后,它内部存储的所有内容也会随之被删除。目前来看,这种解决方案简单直白,但是当 Vector 中的元素被引用后,事情可能会没那么简单。
4.读取Vec中的元素
读取指定位置的元素有两种方式可选:
- 通过下标索引访问。
- 使用
get方法。
4.1 下标
可以像使用数组下标那样,访问vec的成员
let v = Vec::from([11, 22, 33]);
println!("{}", v[0]); // 11
println!("{}", v[1]); // 22
println!("{}", v[2]); // 33使用借用
let mut v = Vec::from([11, 22, 33]);
let num1 = &v[0];
println!("{}", num1); // 11
let num2 = &mut v[1];
*num2 = 66;
println!("{:?}", v); // [11,66,33]4.2 get()
通过get方法,也可以获取vec中的元素,get()方法传入一个下表,返回一个Option
let v = Vec::from([11, 22, 33]);
let first = v.get(0);
match first {
Some(v) => println!("{}", v), // 11
None => println!("唧唧复唧唧"),
}5.遍历Vector
如果想要依次访问数组中的元素,可以使用迭代的方式去遍历数组,这种方式比用下标的方式去遍历数组更安全也更高效(每次下标访问都会触发数组边界检查):
let v = vec![1, 2, 3];
for i in &v {
println!("{i}");
}也可以在迭代过程中,修改 Vector 中的元素:
let mut v = vec![1, 2, 3];
for i in &mut v {
*i += 10
}也可以使用iter()方法返回的迭代器去遍历
let v = vec![1, 2, 3];
for i in v.iter(){
println!("{i}");
}6.Implementations
impl<T> Vec<T, Global>
new()
创建一个空的Vec<T>
并不会立即分配内存,直到将元素压入 vector 为止,vector 才会分配。
pub const fn new() -> Vec<T, Global>返回值:返回一个空的Vec<T>
源码:
#[inline]
#[rustc_const_stable(feature = "const_vec_new", since = "1.39.0")]
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use]
pub const fn new() -> Self {
Vec { buf: RawVec::NEW, len: 0 }
}例子:
let mut vec: Vec<i32> = Vec::new();with_capacity()
创建一个有指定容量的Vec
vector 将能够保存至少 capacity 个元素而无需重新分配。 此方法允许分配比 capacity 更多的元素。 如果 capacity 为 0,则不会分配 vector。
需要注意的是,尽管返回的 vector 具有指定的最小容量,但 vector 的长度为零。
pub fn with_capacity(capacity: usize) -> Vec<T, Global>参数:
- capacity:指定Vec的容量,分配的字节大小不得大于
isize::MAX
返回值:返回一个指定容量的Vec
源码:
#[cfg(not(no_global_oom_handling))]
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[must_use]
pub fn with_capacity(capacity: usize) -> Self {
Self::with_capacity_in(capacity, Global)
}例子:
let v: Vec<u8> = Vec::with_capacity(1000);
println!("{}", v.capacity()) // 1000容量不是长度
- 容量是只这个Vec一共可以容纳多少个元素
- 长度是这个Vec当前已经存放了多少个元素
使用with_capacity()会一次性申请相应的内存空间,可以避免push等操作时,频繁申请空间
with_capacity创建的是Vec的最小容量
如果超出了指定的容量,Vec会再重新申请容量
let mut v: Vec<u8> = Vec::with_capacity(10);
for i in 0..10 {
v.push(i + 1)
}
println!("{}", v.len()); // 10 此处长度已达到指定的容量
v.push(66);
println!("{},{}", v.len(), v.capacity()); // 11 20 // 自动重新申请容量Vec重新申请容量的大小为参数capacity的值
如果新容量超过 isize::MAX 字节,就会出现 panics。
from_raw_parts()
直接从指针、容量和长度创建 Vec<T>
这是非常不安全的,因为没有检查的不变量的数量:
ptr必须使用全局分配器进行分配,例如通过alloc::alloc函数。T需要与分配的ptr具有相同的对齐方式。 (具有不太严格的对齐方式的T是不够的,对齐方式实际上必须等于dealloc的要求,即必须以相同的布局分配和释放内存。)T的大小乘以capacity(以字节为单位的分配大小) 需要与分配指针的大小相同。 (因为与对齐类似,必须使用相同的布局size来调用dealloc。)length需要小于或等于capacity。- 第一个
length值必须是T类型的正确初始化值。 capacity需要是分配指针的容量。- 分配的字节大小不得大于
isize::MAX。 请参见pointer::offset的安全文档。
通过 Vec<T> 分配的任何 ptr 始终支持这些要求。如果支持不,变体,则允许其他分配源。
违反这些可能会导致一些问题,比如破坏分配器的内部数据结构。 例如,从指向长度为 size_t 的 C char 数组的指针构建 Vec<u8> 通常是不安全的,只有当数组最初由 Vec 或 String 分配时,这样做才是安全的。 从 Vec<u16> 及其长度构建一个也不安全,因为分配器关心对齐方式,并且这两种类型具有不同的对齐方式。 缓冲区以对齐方式 2 (对于 u16) 分配,但在将其转换为 Vec<u8> 后,它将以对齐方式释放 1. 为避免这些问题,通常最好使用 slice::from_raw_parts 来进行铸造或转变。
ptr 的所有权有效地转移到 Vec<T>,然后 Vec<T> 可以随意释放,重新分配或更改指针所指向的内存的内容。 调用此函数后,请确保没有其他任何东西使用该指针。
pub unsafe fn from_raw_parts(
ptr: *mut T,
length: usize,
capacity: usize
) -> Vec<T, Global>参数:
- prt:一个指针
- length:Vec的长度
- capacity:Vec的容量
返回值:
源码:
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn from_raw_parts(ptr: *mut T, length: usize, capacity: usize) -> Self {
unsafe { Self::from_raw_parts_in(ptr, length, capacity, Global) }
}例子:
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 {
ptr::write(p.add(i), 4 + i);
}
// 将所有内容放回 Vec
let rebuilt = Vec::from_raw_parts(p, len, cap);
assert_eq!(rebuilt, [4, 5, 6]);
}impl<T, A> Vec<T, A>
impl<T, A> Vec<T, A>
where
A: Allocator,new_in()
用于创建一个使用指定自定义内存分配器的、空的 Vec,是 Vec::new()的“泛化”版本
允许你显式指定一个分配器。Vec后续所有的内存分配和释放(如 push, reserve等操作引发的)都将通过你提供的这个 allocator来完成。
直到将元素压入 vector 为止,vector 才会分配。
pub const fn new_in(alloc: A) -> Vec<T, A>参数:
- alloc:自定义的内存分配器
返回值:返回一个自定义内存分配器的Vec
源码:
#[inline]
#[unstable(feature = "allocator_api", issue = "32838")]
pub const fn new_in(alloc: A) -> Self {
Vec { buf: RawVec::new_in(alloc), len: 0 }
}例子:
#![feature(allocator_api)]
use std::alloc::System;
let mut vec: Vec<i32, _> = Vec::new_in(System);with_capacity_in()
返回值:
源码:
例子:
from_raw_parts_in()
返回值:
源码:
例子:
into_raw_parts()
返回值:
源码:
例子:
into_raw_parts_with_alloc()
返回值:
源码:
例子:
capacity()
返回值:
源码:
例子:
reserve()
返回值:
源码:
例子:
reserve_exact()
返回值:
源码:
例子:
try_reserve()
返回值:
源码:
例子:
try_reserve_exact()
返回值:
源码:
例子:
shrink_to_fit()
返回值:
源码:
例子:
shrink_to()
返回值:
源码:
例子:
into_boxed_slice()
返回值:
源码:
例子:
truncate()
返回值:
源码:
例子:
as_slice()
返回值:
源码:
例子:
as_mut_slice()
返回值:
源码:
例子:
as_ptr()
返回值:
源码:
例子:
as_mut_ptr()
返回值:
源码:
例子:
allocator()
返回值:
源码:
例子:
set_len()
返回值:
源码:
例子:
swap_remove()
返回值:
源码:
例子:
insert()
返回值:
源码:
例子:
remove()
返回值:
源码:
例子:
retain()
返回值:
源码:
例子:
retain_mut()
返回值:
源码:
例子:
dedup_by()
返回值:
源码:
例子:
push()
返回值:
源码:
例子:
push_with_capacity()
返回值:
源码:
例子:
pop()
返回值:
源码:
例子:
append()
返回值:
源码:
例子:
drain()
返回值:
源码:
例子:
clear()
返回值:
源码:
例子:
is_empty()
返回值:
源码:
例子:
split_off()
返回值:
源码:
例子:
resize_with()
返回值:
源码:
例子:
leak()
返回值:
源码:
例子:
spare_capacity_mut()
返回值:
源码:
例子:
split_at_spate_mut()
返回值:
源码:
例子:
返回值:
源码:
例子:
impl<T, A>Vec<T, A>
返回值:
源码:
例子:
resize()
返回值:
源码:
例子:
extends_from_slice()
返回值:
源码:
例子:
extends_from_within()
返回值:
源码:
例子:
返回值:
源码:
例子:
impl<T, A, const N: usize> Vec<[T; N], A>
into_flattened()
返回值:
源码:
例子:
impl<T, A> Vec<T, A>
dedup()
返回值:
源码:
例子:
impl<T, A> Vec<T, A>
splice()
返回值:
源码:
例子:
drain_filter()
返回值:
源码:
例子:
7.Methods from Deref<Target = [T]>
flatten()
返回值:
源码:
例子:
flatten_mut()
返回值:
源码:
例子:
len()
返回值:
源码:
例子:
is_empty()
返回值:
源码:
例子:
first()
返回值:
源码:
例子:
first_mut()
返回值:
源码:
例子:
split_first()
返回值:
源码:
例子:
split_first_mut()
返回值:
源码:
例子:
split_last()
返回值:
源码:
例子:
split_last_mut()
返回值:
源码:
例子:
last()
返回值:
源码:
例子:
last_mut()
返回值:
源码:
例子:
first_chunk_mut()
返回值:
源码:
例子:
split_first_chunk()
返回值:
源码:
例子:
split_first_chunk_mut()
返回值:
源码:
例子:
split_last_chunk()
返回值:
源码:
例子:
split_last_chunk_mut()
返回值:
源码:
例子:
last_chunk()
返回值:
源码:
例子:
last_chunk_mut()
返回值:
源码:
例子:
get()
返回值:
源码:
例子:
get_mut()
返回值:
源码:
例子:
get_unchecked()
返回值:
源码:
例子:
get_unchecked_mut()
返回值:
源码:
例子:
as_ptr()
返回值:
源码:
例子:
as_mut_ptr()
返回值:
源码:
例子:
as_ptr_range()
返回值:
源码:
例子:
as_mut_ptr_range()
返回值:
源码:
例子:
swap()
返回值:
源码:
例子:
swap_unchecked()
返回值:
源码:
例子:
reverse()
返回值:
源码:
例子:
iter()
返回值:
源码:
例子:
iter_mut()
返回值:
源码:
例子:
windows()
返回值:
源码:
例子:
chunks()
返回值:
源码:
例子:
chunks_mut()
返回值:
源码:
例子:
chunks_exact()
返回值:
源码:
例子:
chunks_exact_mut()
返回值:
源码:
例子:
as_chunks_unchecked()
返回值:
源码:
例子:
as_chunks()
返回值:
源码:
例子:
as_rchunks()
返回值:
源码:
例子:
array_chunks()
返回值:
源码:
例子:
as_chunks_unchecked_mut()
返回值:
源码:
例子:
as_chunks_mut()
返回值:
源码:
例子:
as_rchunks_mut()
返回值:
源码:
例子:
array_chunks_mut()
返回值:
源码:
例子:
array_windows()
返回值:
源码:
例子:
rchunks()
返回值:
源码:
例子:
rchunks_mut()
返回值:
源码:
例子:
rchunks_exact()
返回值:
源码:
例子:
rchunks_exact_mut()
返回值:
源码:
例子:
group_by()
返回值:
源码:
例子:
group_by_mut()
返回值:
源码:
例子:
split_at()
返回值:
源码:
例子:
split_at_mut()
返回值:
源码:
例子:
split_at_unchecked()
返回值:
源码:
例子:
split_at_mut_unchecked()
返回值:
源码:
例子:
split_array_ref()
返回值:
源码:
例子:
aplit_array_mut()
返回值:
源码:
例子:
rsplit_array_ref()
返回值:
源码:
例子:
rsplit_array_mut()
返回值:
源码:
例子:
split()
返回值:
源码:
例子:
split_mut()
返回值:
源码:
例子:
split_inclusive()
返回值:
源码:
例子:
split_inclusive_mut()
返回值:
源码:
例子:
rsplit()
返回值:
源码:
例子:
rsplit_mut()
返回值:
源码:
例子:
splitn()
返回值:
源码:
例子:
splitn_mut()
返回值:
源码:
例子:
rsplitn()
返回值:
源码:
例子:
rsplitn_mut()
返回值:
源码:
例子:
contains()
返回值:
源码:
例子:
starts_with()
返回值:
源码:
例子:
ends_with()
返回值:
源码:
例子:
strip_prefix()
返回值:
源码:
例子:
strip_suffix()
返回值:
源码:
例子:
binary_search()
返回值:
源码:
例子:
binary_search_by()
返回值:
源码:
例子:
binary_search_by_key()
返回值:
源码:
例子:
sort_unstable()
返回值:
源码:
例子:
sort_unstable_by()
返回值:
源码:
例子:
sort_unstable_by_key()
返回值:
源码:
例子:
select_nth_unstable()
返回值:
源码:
例子:
select_nth_unstable_by()
返回值:
源码:
例子:
select_nth_unstable_by_key()
返回值:
源码:
例子:
partition_dedup()
返回值:
源码:
例子:
partition_dedup_by()
返回值:
源码:
例子:
partition_dedup_by_key()
返回值:
源码:
例子:
rotate_left()
返回值:
源码:
例子:
rotate_right()
返回值:
源码:
例子:
fill()
返回值:
源码:
例子:
fill_with()
返回值:
源码:
例子:
clone_from_slice()
返回值:
源码:
例子:
copy_from_slice()
返回值:
源码:
例子:
copy_within()
返回值:
源码:
例子:
swap_with_slice()
返回值:
源码:
例子:
align_to()
返回值:
源码:
例子:
align_to_mut()
返回值:
源码:
例子:
as_simd()
返回值:
源码:
例子:
as_simd_mut()
返回值:
源码:
例子:
is_sorted()
返回值:
源码:
例子:
is_sorted_by()
返回值:
源码:
例子:
partition_point()
返回值:
源码:
例子:
take()
返回值:
源码:
例子:
take_mut()
返回值:
源码:
例子:
take_first()
返回值:
源码:
例子:
take_first_mut()
返回值:
源码:
例子:
take_last()
返回值:
源码:
例子:
take_last_mut()
返回值:
源码:
例子:
get_many_unchecked_mut()
返回值:
源码:
例子:
get_many_mut()
返回值:
源码:
例子:
sort_floats()
返回值:
源码:
例子:
sort_floats()
返回值:
源码:
例子:
is_ascii()
返回值:
源码:
例子:
as_ascii()
返回值:
源码:
例子:
as_ascii_unchecked()
返回值:
源码:
例子:
eq_ignore_ascii_case()
返回值:
源码:
例子:
make_ascii_uppercase()
返回值:
源码:
例子:
make_ascii_lowercase()
返回值:
源码:
例子:
escape_ascii()
返回值:
源码:
例子:
trim_ascii_start()
返回值:
源码:
例子:
trim_ascii_end()
返回值:
源码:
例子:
trim_ascii()
返回值:
源码:
例子:
as_str()
返回值:
源码:
例子:
as_bytes()
返回值:
源码:
例子:
to_ascii_uppercase()
返回值:
源码:
例子:
to_ascii_lowercase()
返回值:
源码:
例子:
sort()
返回值:
源码:
例子:
sort_by()
返回值:
源码:
例子:
sort_by_key()
返回值:
源码:
例子:
sort_by_cached_key()
返回值:
源码:
例子:
to_vet()
返回值:
源码:
例子:
to_vet_in()
返回值:
源码:
例子:
repeat()
返回值:
源码:
例子:
concat()
返回值:
源码:
例子:
join()
返回值:
源码:
例子:
connect()
返回值:
源码:
例子:
8.Trait 实现
返回值:
源码:
例子:
impl<T, A> AsMut<[T]> for Vec<T, A>
```
#### s_mut()