当前位置: 首页 > news >正文

详解Rust标准库:Vec向量

查看本地官方文档

安装rust后运行

rustup doc

查看The Standard Library即可获取标准库内容

std::vec::Vec定义

Vec除了可以作为动态数组还可以模拟为一个栈,仅使用pushpop即可

Vec默认分配在堆上,对于一个容量为4,有两个元素ab的向量内存布局如下

            ptr      len  capacity+--------+--------+--------+| 0x0123 |      2 |      4 |+--------+--------+--------+|v
Heap   +--------+--------+--------+--------+|    'a' |    'b' | uninit | uninit |+--------+--------+--------+--------+

Vec定义

pub struct Vec<T, A: Allocator = Global> {// 存储了动态数组的元素数据,并且根据需要可以动态地增长或收缩以容纳更多或更少的元素buf: RawVec<T, A>,// 表示当前Vec中实际存储的元素数量len: usize,
}

RawVec:定义

pub(crate) struct RawVec<T, A: Allocator = Global> {// 这是一个Unique<T>类型的指针,指向分配的内存块中存储元素的起始位置。这个指针用于访问和操作存储在RawVec中的元素ptr: Unique<T>,// 代表RawVec的容量,容量通常会随着元素的添加而动态调整,当需要更多空间时,会进行内存重新分配以增加容量。同时,对于零大小类型(ZST),容量的处理方式有所不同,capacity()方法会在这种情况下返回usize::MAXcap: Cap,// 分配器负责分配和释放内存,以及管理内存的生命周期,通过这个分配器,RawVec可以根据需要动态地分配和调整内存空间来存储元素alloc: A,
}

每次进行自动分配容量的开销比预先分配容量大得多,所以预先分配容量可以减少分配的开销,建议使用with_capacity预先分配容量

方法

with_capacity:创建一个具有指定初始容量的Vec

fn main() {let mut v = Vec::with_capacity(5);v.push(1);v.push(2);println!("Capacity: {}", v.capacity()); // 输出初始容量 5,目前只使用了部分容量// Capacity: 5
}

from_raw_parts:从给定的原始指针和长度创建一个Vec,使用时需要非常小心,确保内存管理正确

  • ptr必须使用全局分配器进行分配,例如通过alloc::alloc函数
  • T需要和ptr的对齐方式相同。(不那么严格的对齐是不够的,对齐确实需要相等才能满足dealloc要求,即内存必须以相同的布局分配和释放。)
  • T的大小乘以容量(即分配的大小(以字节为单位)需要与指针分配的大小相同。(因为与对齐类似,必须以相同的布局大小调用dealloc。)
  • Length必须小于或等于capacity容量
  • 第一个Length值必须正确初始化T类型的值
  • 容量需要是指针分配的容量
  • 分配的字节大小必须不大于isize::MAX
use std::ptr;
use std::mem;
fn main() {let v = vec![1, 2, 3];let mut v = mem::ManuallyDrop::new(v);let p = v.as_mut_ptr();let len = v.len();let cap = v.capacity();unsafe {// 覆盖内存for i in 0..len {ptr::write(p.add(i), 4 + i);}// 将内存重新构建为Veclet rebuilt = Vec::from_raw_parts(p, len, cap);println!("{:?}", rebuilt);// [4, 5, 6]}
}

capacity:返回Vec的当前容量

fn main() {let mut v = Vec::with_capacity(5);v.push(1);v.push(2);println!("Capacity: {}", v.capacity()); // 输出初始容量 5,目前只使用了部分容量// Capacity: 5
}

reserve:增加Vec的容量,确保至少可以容纳指定数量的更多元素

fn main() {let mut v: Vec<i32> = Vec::new();v.reserve(10);println!("Capacity after reserve: {}", v.capacity());// Capacity after reserve: 10
}

reserve_exact:精确地将Vec的容量调整为指定值,容量为vec.len()+addtitional

fn main() {let mut v = Vec::new();v.push(1);v.push(2);v.reserve_exact(5);println!("Capacity after reserve_exact: {}", v.capacity());// Capacity after reserve_exact: 7
}

try_reserve:尝试增加Vec的容量,如果无法增加则返回false

fn main() {let mut v: Vec<i32> = Vec::new();if v.try_reserve(1).is_ok() {println!("Reserved successfully");// Reserved successfully} else {println!("Failed to reserve");}
}

try_reserve_exact:尝试将Vec的容量精确调整为指定值,如果无法调整则返回false

fn main() {let mut v: Vec<i32> = Vec::new();if v.try_reserve_exact(5).is_ok() {println!("Reserved exactly successfully");// Reserved exactly successfully} else {println!("Failed to reserve exactly");}
}

shrink_to_fit:将Vec的容量调整为与当前长度相等,释放多余的内存

fn main() {let mut v = Vec::with_capacity(10);v.push(1);v.push(2);v.shrink_to_fit();println!("Capacity after shrink_to_fit: {}", v.capacity());// Capacity after shrink_to_fit: 2
}

shrink_to:尽可能将Vec的容量缩小为指定最小容量,释放多余的内存

fn main() {let mut v = Vec::with_capacity(10);v.push(1);v.push(2);v.shrink_to(1);println!("Capacity after shrink_to_fit: {}", v.capacity());// Capacity after shrink_to_fit: 2
}

into_boxed_slice:将Vec转换为Box<[T]>,所有权转移

fn main() {let v = vec![1, 2, 3];let boxed_slice = v.into_boxed_slice();println!("{}", boxed_slice[0]);// 1
}

truncate:截断Vec,使其长度不超过指定值

fn main() {let mut v = vec![1, 2, 3, 4, 5];v.truncate(3);println!("Truncated vector: {:?}", v);// Truncated vector: [1, 2, 3]
}

as_slice:返回Vec的不可变切片引用

fn main() {let v = vec![1, 2, 3];let slice = v.as_slice();for item in slice {println!("{}", item);}// 1// 2// 3
}

as_mut_slice:返回Vec的可变切片引用

fn main() {let mut v = vec![1, 2, 3];let slice = v.as_mut_slice();slice[0] = 4;println!("Modified vector: {:?}", v);// Modified vector: [4, 2, 3]
}

as_ptr:返回指向向量缓冲区的原始指针或悬空的原始指针

fn main() {let x = vec![1, 2, 4];let x_ptr = x.as_ptr();unsafe {for i in 0..x.len() {// 将指针加i即右移i位,然后解引用,得到对应位置的元素1,2,4// 1按位左移相当于*2assert_eq!(*x_ptr.add(i), 1 << i);}}
}

as_mut_ptr:返回指向Vec缓冲区的不安全可变指针,或悬空的指针

fn main() {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);}println!("{:?}", x);// [0, 1, 2, 3]
}

set_len:低级操作,用于修改向量长度

  • new_len必须小于或等于 capacity()
  • 必须初始化元素
fn main() {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);}println!("{:?}", x);// [0, 1, 2, 3]
}

swap_remove:从Vec中删除一个元素并返回它,被删除的元素位置将被Vec的最后一个元素替换,不保留其余元素的顺序,如果需要保留元素顺序请使用remove

fn main() {let mut v = vec!["foo", "bar", "baz", "qux"];let _ = v.swap_remove(1);println!("{:?}", v);// ["foo", "qux", "baz"]
}

insert:在指定位置插入一个元素

fn main() {let mut v = vec![1, 2, 3];v.insert(1, 4);println!("Inserted vector: {:?}", v);// Inserted vector: [1, 4, 2, 3]
}

remove:移除指定位置的元素并返回它,同时调整向量的长度

fn main() {let mut v = vec![1, 2, 3];let removed = v.remove(1);println!("Removed element: {}", removed);// Removed element: 2println!("After removal: {:?}", v);// After removal: [1, 3]
}

retain:保留满足给定谓词的元素,删除不满足的元素

fn main() {let mut v = vec![1, 2, 3, 4];v.retain(|&x| x % 2 == 0);println!("Retained vector: {:?}", v);// Retained vector: [2, 4]
}

retain_mut:保留满足给定谓词的元素,删除不满足的元素,并且可以在过程中修改元素

fn main() {let mut v = vec![1, 2, 3, 4];v.retain_mut(|x| {if *x % 2 == 0 {*x *= 2;true} else {false}});println!("After retain_mut: {:?}", v);// After retain_mut: [4, 8]
}

dedup_by_key:根据自定义的键提取函数去除连续重复的元素

fn main() {let mut vec = vec![10, 20, 21, 30, 20];vec.dedup_by_key(|i| *i / 10);println!("{:?}", vec);// [10, 20, 30, 20]
}

dedup_by:使用自定义的比较函数去除连续重复的元素

fn main() {let mut v = vec![1, 2, 2, 3];v.dedup_by(|a, b| a == b);println!("After dedup_by: {:?}", v);// After dedup_by: [1, 2, 3]
}

push:向Vec的末尾添加一个元素

fn main() {let mut v = Vec::new();v.push(1);v.push(2);println!("Pushed vector: {:?}", v);// Pushed vector: [1, 2]
}

pop:移除并返回Vec的末尾元素,如果Vec为空则返回None

fn main() {let mut v = vec![1, 2, 3];if let Some(item) = v.pop() {println!("Popped item: {}", item);// Popped item: 3}println!("After pop: {:?}", v);// After pop: [1, 2]
}

append:将另一个Vec的内容追加到当前Vec的末尾

fn main() {let mut v1 = vec![1, 2];let mut v2 = vec![3, 4];v1.append(&mut v2);println!("Appended vector: {:?}", v1);// Appended vector: [1, 2, 3, 4]
}

drain:移除并返回一个范围的元素,返回一个迭代器

fn main() {let mut v = vec![1, 2, 3, 4];let drained = v.drain(1..3);println!("Drained elements: {:?}", drained.collect::<Vec<_>>());// Drained elements: [2, 3]println!("After drain: {:?}", v);// After drain: [1, 4]
}

clear:移除Vec中的所有元素

fn main() {let mut v = vec![1, 2, 3];v.clear();println!("Cleared vector: {:?}", v);// Cleared vector: []
}

len:返回Vec中元素的数量

fn main() {let v = vec![1, 2, 3];println!("Length of vector: {}", v.len());// Length of vector: 3
}

is_empty:判断Vec是否为空

fn main() {let v: Vec<i32> = Vec::new();println!("Is vector empty? {}", v.is_empty());// Is vector empty? truelet v2 = vec![1];println!("Is vector empty? {}", v2.is_empty());// Is vector empty? false
}

split_off:在指定位置将Vec分割成两个部分,返回后半部分,原向量变为前半部分

fn main() {let mut v = vec![1, 2, 3, 4];let second_half = v.split_off(2);println!("First half: {:?}", v);// First half: [1, 2]println!("Second half: {:?}", second_half);// Second half: [3, 4]
}

resize_with:调整Vec的大小为指定大小,使用给定的闭包来填充新添加的元素

fn main() {let mut v = vec![1, 2];v.resize_with(4, || 0);println!("After resize_with: {:?}", v);// After resize_with: [1, 2, 0, 0]
}

leak:将Vec的所有权转移到堆上而不进行清理,防止向量在超出作用域时被释放。通常用于需要手动管理内存的情况


spare_capacity_mut:返回向量当前未使用的容量。通常用于了解向量内部的内存分配情况


resize:调整Vec的长度为指定大小,如果新长度大于当前长度,新添加的元素使用默认值填充

fn main() {let mut v = vec![1, 2];v.resize(4, 0);println!("Resized vector: {:?}", v);// Resized vector: [1, 2, 0, 0]
}

extend_from_slice:从一个切片中扩展Vec,将切片中的元素添加到Vec的末尾

fn main() {let mut v = vec![1, 2];let slice = &[3, 4];v.extend_from_slice(slice);println!("Extended vector: {:?}", v);// Extended vector: [1, 2, 3, 4]
}

extend_from_within:从向量自身的一部分扩展向量

fn main() {let mut v = vec![1, 2, 3, 4];v.extend_from_within(1..3);println!("After extend_from_within: {:?}", v);// After extend_from_within: [1, 2, 3, 4, 2, 3]
}

into_flattened:将包含迭代器的向量转换为一个扁平的迭代器

fn main() {let v = vec![vec![1, 2], vec![3, 4]];let flattened = v.into_iter().flatten().collect::<Vec<_>>();println!("Flattened vector: {:?}", flattened);// Flattened vector: [1, 2, 3, 4]
}

dedup:删除Vec中连续重复的元素,只保留第一个出现的元素

fn main() {let mut v = vec![1, 1, 2, 2, 3];v.dedup();println!("Deduped vector: {:?}", v);// Deduped vector: [1, 2, 3]
}

splice:创建一个拼接迭代器,用给定迭代器替换载体中的指定范围,并生成删除的项

fn main() {let mut v = vec![1, 2, 3, 4];let new = [7, 8, 9];let u: Vec<_> = v.splice(1..3, new).collect();println!("{:?}", u);// [2, 3]println!("{:?}", v);// [1, 7, 8, 9, 4]
}

Deref上的方法

as_flattened:将切片中包含的切片扁平化为单个切片

fn main() {let v1 = [[1, 2, 3],[4, 5, 6],].as_flattened();println!("{:?}", v1);// [1, 2, 3, 4, 5, 6]
}

as_flattened_mut将切片中包含的切片扁平化为可变切片

fn main() {fn add_5_to_all(slice: &mut [i32]) {for i in slice {*i += 5;}}let mut array = [[1, 2, 3],[4, 5, 6],[7, 8, 9],];array.as_flattened_mut();add_5_to_all(array.as_flattened_mut());println!("{:?}", array);// [[6, 7, 8], [9, 10, 11], [12, 13, 14]]
}

is_ascii:判断Vec中的所有字符是否都是 ASCII 字符

fn main() {let v = vec![1, 2, 3];println!("Is ASCII? {}", v.is_ascii());// Is ASCII? true
}

make_ascii_uppercase:就地将切片转换为ASCII大写等效项
make_ascii_lowercase:就地将切片转换为ASCII小写等效项

fn main() {let mut v = vec![97, 98, 65, 66, 200];println!("Original vector: {:?}", v);// Original vector: [97, 98, 65, 66, 200]v.make_ascii_uppercase();println!("After make_ascii_uppercase: {:?}", v);// After make_ascii_uppercase: [65, 66, 65, 66, 200]v.make_ascii_lowercase();println!("After make_ascii_lowercase: {:?}", v);// After make_ascii_lowercase: [97, 98, 97, 98, 200]
}

escape_ascii:返回一个迭代器,该迭代器生成此切片的转义版本, 将其视为 ASCII 字符串

fn main() {let s = b"0\t\r\n'\"\\\x9d";let escaped = s.escape_ascii().to_string();println!("{}", escaped);// 0\t\r\n\'\"\\\x9d
}

len:返回切片中的元素数

fn main() {let a = [1, 2, 3];println!("{:?}", a.len());// 3
}

is_empty:判断切片是否为空

fn main() {let b: &[i32] = &[];println!("Is emoty: {}", b.is_empty());// Is emoty: true
}

first:返回切片的第一个元素

fn main() {let v = [10, 40, 30];println!("{}", v.first().unwrap());// 10
}

first_mut:返回指向slice的第一个元素的可变指针

fn main() {let x = &mut [0, 1, 2];if let Some(first) = x.first_mut() {*first = 5;}println!("{:?}", x);// [5, 1, 2]
}

split_first:将Vec分割为第一个元素和剩余部分,如果向量为空,则返回None

fn main() {let v = vec![1, 2, 3];if let Some((first, rest)) = v.split_first() {println!("First element: {}", first);// First element: 1println!("Rest: {:?}", rest);// Rest: [2, 3]}
}

split_last:将Vec分割为最后一个元素和前面的部分,如果向量为空,则返回None

fn main() {let v = vec![1, 2, 3];if let Some((front, last)) = v.split_last() {println!("Front: {:?}", front);// Front: 3println!("Last element: {:?}", last);// Last element: [1, 2]}
}

get:通过索引安全地访问Vec中的元素,如果索引超出范围,则返回None

fn main() {let v = vec![1, 2, 3];if let Some(item) = v.get(1) {println!("Element at index 1: {}", item);// Element at index 1: 2}
}

get_mut:通过索引安全地获取Vec中元素的可变引用,如果索引超出范围,则返回None

fn main() {let mut v = vec![1, 2, 3];if let Some(item) = v.get_mut(1) {*item = 4;}println!("Modified vector: {:?}", v);// Modified vector: [1, 4, 3]
}

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

fn main() {let x = &[1, 2, 4];unsafe {println!("{}", x.get_unchecked(1));// 2}
}

get_unchecked_mut:返回对元素或子切片的可变引用,不执行边界检查

fn main() {let x = &mut [1, 2, 4];unsafe {let elem = x.get_unchecked_mut(1);*elem = 13;}println!("{:?}", x);// [1, 13, 4]
}

swap:交换Vec中两个指定索引的元素

fn main() {let mut v = vec![1, 2, 3];v.swap(0, 2);println!("Swapped vector: {:?}", v);// Swapped vector: [3, 2, 1]
}

reverse:反转Vec中元素的顺序

fn main() {let mut v = vec![1, 2, 3];v.reverse();println!("Reversed vector: {:?}", v);// Reversed vector: [3, 2, 1]
}

iter:返回一个不可变的迭代器,用于遍历Vec中的元素

fn main() {let v = vec![1, 2, 3];for item in v.iter() {println!("{}", item);}// 1// 2// 3
}

iter_mut:返回一个可变的迭代器,用于遍历Vec中的元素

fn main() {let mut v = vec![1, 2, 3];for item in v.iter_mut() {*item *= 2;}println!("Modified vector: {:?}", v);// Modified vector: [2, 4, 6]
}

windows:返回一个迭代器,产生固定大小的窗口切片

fn main() {let v = vec![1, 2, 3, 4];for window in v.windows(2) {println!("Window: {:?}", window);}// Window: [1, 2]// Window: [2, 3]// Window: [3, 4]
}

chunks:将Vec分割成不重叠的子切片,每个子切片的大小尽可能接近但不超过指定的大小

fn main() {let v = vec![1, 2, 3, 4, 5];for chunk in v.chunks(2) {println!("Chunk: {:?}", chunk);}// Chunk: [1, 2]// Chunk: [3, 4]// Chunk: [5]
}

chunks_mut:与chunks类似,但返回可变的子切片迭代器

fn main() {let mut v = vec![1, 2, 3, 4, 5];for chunk in v.chunks_mut(2) {for item in chunk {*item *= 2;}}println!("Modified vector with chunks_mut: {:?}", v);// Modified vector with chunks_mut: [2, 4, 6, 8, 10]
}

chunks_exact:将Vec分割成大小完全为指定大小的不重叠子切片,如果向量的长度不是指定大小的整数倍,则最后一个子切片可能小于指定大小。如果向量的长度不能被指定大小整除,则返回一个空迭代器

fn main() {let v = vec![1, 2, 3, 4];for chunk in v.chunks_exact(2) {println!("Exact chunk: {:?}", chunk);}// Exact chunk: [1, 2]// Exact chunk: [3, 4]
}

chunks_exact_mut:与chunks_exact类似,但返回可变的子切片迭代器

fn main() {let mut v = vec![1, 2, 3, 4];for chunk in v.chunks_exact_mut(2) {for item in chunk {*item *= 2;}}println!("Modified vector with chunks_exact_mut: {:?}", v);// Modified vector with chunks_exact_mut: [2, 4, 6, 8]
}

rchunks:从向量的末尾开始分割成不重叠的子切片,每个子切片的大小尽可能接近但不超过指定的大小

fn main() {let v = vec![1, 2, 3, 4, 5];for chunk in v.rchunks(2) {println!("Reverse chunk: {:?}", chunk);}// Reverse chunk: [4, 5]// Reverse chunk: [2, 3]// Reverse chunk: [1]
}

rchunks_mut:与rchunks类似,但返回可变的子切片迭代器

fn main() {let mut v = vec![1, 2, 3, 4, 5];for chunk in v.rchunks_mut(2) {for item in chunk {*item *= 2;}}println!("Modified vector with rchunks_mut: {:?}", v);// Modified vector with rchunks_mut: [2, 4, 6, 8, 10]
}

rchunks_exact:从向量的末尾开始分割成大小完全为指定大小的不重叠子切片,如果向量的长度不是指定大小的整数倍,则最后一个子切片可能小于指定大小。如果向量的长度不能被指定大小整除,则返回一个空迭代器

fn main() {let v = vec![1, 2, 3, 4, 4, 5];for chunk in v.rchunks_exact(2) {println!("Reverse exact chunk: {:?}", chunk);}
}
// Reverse exact chunk: [4, 5]
// Reverse exact chunk: [3, 4]
// Reverse exact chunk: [1, 2]

rchunks_exact_mut:与rchunks_exact类似,但返回可变的子切片迭代器

fn main() {let mut v = vec![1, 2, 3, 4];for chunk in v.rchunks_exact_mut(2) {for item in chunk {*item *= 2;}}println!("Modified vector with rchunks_exact_mut: {:?}", v);// Modified vector with rchunks_exact_mut: [2, 4, 6, 8]
}

chunk_by:根据给定的谓词将Vec分割成不重叠的子切片,只要谓词对连续的元素返回相同的值,这些元素就会被分到同一个子切片中

fn main() {let v = vec![1, 2, 3, 4, 5];let chunks = v.chunk_by(|a, b| a % 2 == b % 2);for chunk in chunks {println!("Chunk by predicate: {:?}", chunk);}// Chunk by predicate: [1]// Chunk by predicate: [2]// Chunk by predicate: [3]// Chunk by predicate: [4]// Chunk by predicate: [5]
}

chunk_by_mut:与chunk_by类似,但返回可变的子切片迭代器

fn main() {let mut v = vec![1, 2, 3, 4, 5];let chunks = v.chunk_by_mut(|a, b| a % 2 == b % 2);for chunk in chunks {for item in chunk {*item *= 2;}}println!("Modified vector with chunk_by_mut: {:?}", v);// Modified vector with chunk_by_mut: [2, 4, 6, 8, 10]
}

split_at:将Vec在指定位置分割成两个部分,返回一个包含两个切片的元组

fn main() {let v = vec![1, 2, 3, 4, 5];let (left, right) = v.split_at(2);println!("Left: {:?}", left);// Left: [1, 2]println!("Right: {:?}", right);// Right: [3, 4, 5]
}

split_at_mut:与split_at类似,但返回可变的两个切片

fn main() {let mut v = vec![1, 2, 3, 4, 5];let (left, right) = v.split_at_mut(2);for item in left.iter_mut() {*item *= 2;}println!("Modified left and right: {:?}, {:?}", left, right);// Modified left and right: [2, 4], [3, 4, 5]
}

split_at_unchecked:通过索引不安全地将Vec在指定位置分割成两个部分,不进行边界检查。这是一个危险的操作,可能导致未定义行为如果索引超出范围

fn main() {let v = vec![1, 2, 3, 4, 5];let (left, right) = unsafe { v.split_at_unchecked(2) };println!("Unchecked split left: {:?}", left);// Unchecked split left: [1, 2]println!("Unchecked split right: {:?}", right);// Unchecked split right: [3, 4, 5]
}

split_at_mut_unchecked:与split_at_unchecked类似,但返回可变的两个切片。同样是危险的操作,不进行边界检查

fn main() {let mut v = vec![1, 2, 3, 4, 5];let (left, right) = unsafe { v.split_at_mut_unchecked(2) };for item in left.iter_mut() {*item *= 2;}println!("Modified unchecked left and right: {:?}, {:?}", left, right);// Modified unchecked left and right: [2, 4], [3, 4, 5]
}

split_at_checked:通过索引安全地将Vec在指定位置分割成两个部分,如果索引超出范围则返回None

fn main() {let v = vec![1, 2, 3, 4, 5];if let Some((left, right)) = v.split_at_checked(2) {println!("Checked split left: {:?}", left);// Checked split left: [1, 2]println!("Checked split right: {:?}", right);// Checked split right: [3, 4, 5]}
}

split_at_mut_checked:与split_at_checked类似,但返回可变的两个切片。如果索引超出范围则返回None

fn main() {let mut v = vec![1, 2, 3, 4, 5];if let Some((left, right)) = v.split_at_mut_checked(2) {for item in left.iter_mut() {*item *= 2;}println!("Modified checked left and right: {:?}, {:?}", left, right);// Modified checked left and right: [2, 4], [3, 4, 5]}
}

split:根据给定的值将Vec分割成多个子切片,返回一个迭代器

fn main() {let v = vec![1, 2, 3, 4, 5];let splits = v.split(|&x| x == 3);for split in splits {println!("Split: {:?}", split);}// Split: [1, 2]// Split: [4, 5]
}

split_mut:与split类似,但返回可变的子切片迭代器

fn main() {let mut v = vec![1, 2, 3, 4, 5];let splits = v.split_mut(|&x| x == 3);for split in splits {for item in split {*item *= 2;}}println!("Modified vector with split_mut: {:?}", v);// Modified vector with split_mut: [2, 4, 3, 8, 10]
}

split_inclusive:根据给定的值将Vec分割成多个子切片,包括分割值在子切片中,返回一个迭代器

fn main() {let v = vec![1, 2, 3, 4, 5];let splits = v.split_inclusive(|&x| x == 3);for split in splits {println!("Inclusive split: {:?}", split);}// Inclusive split: [1, 2, 3]// Inclusive split: [4, 5]
}

split_inclusive_mut:与split_inclusive类似,但返回可变的子切片迭代器

fn main() {let mut v = vec![1, 2, 3, 4, 5];let splits = v.split_inclusive_mut(|&x| x == 3);for split in splits {for item in split {*item *= 2;}}println!("Modified vector with split_inclusive_mut: {:?}", v);// Modified vector with split_inclusive_mut: [2, 4, 6, 8, 10]
}

rsplit:从向量的末尾开始根据给定的值将Vec分割成多个子切片,返回一个迭代器

fn main() {let v = vec![1, 2, 3, 4, 5];let splits = v.rsplit(|&x| x == 3);for split in splits {println!("Reverse split: {:?}", split);}// Reverse split: [4, 5]// Reverse split: [1, 2]
}

rsplit_mut:与rsplit类似,但返回可变的子切片迭代器

fn main() {let mut v = vec![1, 2, 3, 4, 5];let splits = v.rsplit_mut(|&x| x == 3);for split in splits {for item in split {*item *= 2;}}println!("Modified vector with rsplit_mut: {:?}", v);// Modified vector with rsplit_mut: [2, 4, 3, 8, 10]
}

splitn:将Vec分割成指定数量的子切片,返回一个迭代器

fn main() {let v = vec![1, 2, 3, 4, 5];let splits = v.splitn(3, |&x| x % 2 == 0);for split in splits {println!("Splitn: {:?}", split);}// Splitn: [1]// Splitn: [3]// Splitn: [5]
}

splitn_mut:与splitn类似,但返回可变的子切片迭代器

fn main() {let mut v = vec![1, 2, 3, 4, 5];let splits = v.splitn_mut(3, |&x| x % 2 == 0);for split in splits {for item in split {*item *= 2;}}println!("Modified vector with splitn_mut: {:?}", v);// Modified vector with splitn_mut: [2, 2, 6, 4, 10]
}

rsplitn:从向量的末尾开始将Vec分割成指定数量的子切片,返回一个迭代器

fn main() {let v = vec![1, 2, 3, 4, 5];let splits = v.rsplitn(3, |&x| x % 2 == 0);for split in splits {println!("Reverse splitn: {:?}", split);}// Reverse splitn: [5]// Reverse splitn: [3]// Reverse splitn: [1]
}

rsplitn_mut:与rsplitn类似,但返回可变的子切片迭代器

fn main() {let mut v = vec![1, 2, 3, 4, 5];let splits = v.rsplitn_mut(3, |&x| x % 2 == 0);for split in splits {for item in split {*item *= 2;}}println!("Modified vector with rsplitn_mut: {:?}", v);// Modified vector with rsplitn_mut: [2, 2, 6, 4, 10]
}

contains:判断Vec中是否包含指定元素

fn main() {let v = vec![1, 2, 3];println!("Contains 2? {}", v.contains(&2));// Contains 2? true
}

starts_with:判断Vec是否以指定的切片开头

fn main() {let v = vec![1, 2, 3, 4, 5];let slice = &[1, 2];println!("Starts with slice? {}", v.starts_with(slice));// Starts with slice? true
}

ends_with:判断Vec是否以指定的切片结尾

fn main() {let v = vec![1, 2, 3, 4, 5];let slice = &[4, 5];println!("Ends with slice? {}", v.ends_with(slice));// Ends with slice? true
}

strip_prefix:如果Vec以指定的切片开头,则移除该切片并返回Some包含剩余部分,否则返回None

fn main() {let v = vec![1, 2, 3, 4, 5];if let Some(stripped) = v.strip_prefix(&[1, 2]) {println!("Stripped vector: {:?}", stripped);}// Stripped vector: [3, 4, 5]
}

strip_suffix::如果Vec以指定的切片结尾,则移除该切片并返回Some包含剩余部分,否则返回None

fn main() {let v = vec![1, 2, 3, 4, 5];if let Some(stripped) = v.strip_suffix(&[4, 5]) {println!("Stripped vector: {:?}", stripped);// Stripped vector: [1, 2, 3]}
}

binary_search:在已排序的Vec中进行二分查找,返回一个Result类型,表示查找结果。如果找到元素,返回Ok(index),其中index是元素在向量中的位置;如果未找到,返回Err(index),其中index是元素应该插入的位置以保持向量有序

fn main() {let v = vec![1, 2, 3, 4, 5];let result = v.binary_search(&3);match result {Ok(index) => println!("Found at index {}", index),// Found at index 2Err(index) => println!("Not found, would be inserted at index {}", index),}
}

binary_search_by:使用自定义的比较函数在已排序的Vec中进行二分查找

fn main() {let v = vec![1, 2, 3, 4, 5];let result = v.binary_search_by(|x| x.cmp(&3));match result {Ok(index) => println!("Found at index {}", index),// Found at index 2Err(index) => println!("Not found, would be inserted at index {}", index),}
}

binary_search_by_key:使用自定义的键提取函数和比较函数在已排序的Vec中进行二分查找

fn main() {let v = vec![(1, "a"), (2, "b"), (3, "c")];let result = v.binary_search_by_key(&2, |&(k, _)| k);match result {Ok(index) => println!("Found at index {}", index),// Found at index 1Err(index) => println!("Not found, would be inserted at index {}", index),}
}

sort_unstable:对Vec中的元素进行不稳定排序。不稳定排序可能会改变相等元素的相对顺序

fn main() {let mut v = vec![3, 1, 2];v.sort_unstable();println!("Unstable sorted vector: {:?}", v);// Unstable sorted vector: [1, 2, 3]
}

sort_unstable_by:使用自定义的比较函数对Vec中的元素进行不稳定排序

fn main() {let mut v = vec![(3, "c"), (1, "a"), (2, "b")];v.sort_unstable_by(|a, b| a.0.cmp(&b.0));println!("Unstable sorted by key vector: {:?}", v);// Unstable sorted by key vector: [(1, "a"), (2, "b"), (3, "c")]
}

sort_unstable_by_key:使用自定义的键提取函数对Vec中的元素进行不稳定排序

fn main() {let mut v = vec![(3, "c"), (1, "a"), (2, "b")];v.sort_unstable_by_key(|&(k, _)| k);println!("Unstable sorted by extracted key vector: {:?}", v);// Unstable sorted by extracted key vector: [(1, "a"), (2, "b"), (3, "c")]
}

select_nth_unstable:在Vec中选择第 n 小的元素,并将其移动到正确的位置,同时将小于它的元素移动到左边,大于它的元素移动到右边,但不保证相对顺序


select_nth_unstable_by:使用自定义的比较函数在Vec中选择第 n 小的元素,并进行不稳定排序


select_nth_unstable_by_key:使用自定义的键提取函数在Vec中选择第 n 小的元素,并进行不稳定排序


rotate_left:将Vec向左旋转指定的步数

fn main() {let mut v = vec![1, 2, 3, 4, 5];v.rotate_left(2);println!("Rotated left vector: {:?}", v);// Rotated left vector: [3, 4, 5, 1, 2]
}

rotate_right:将Vec向右旋转指定的步数

fn main() {let mut v = vec![1, 2, 3, 4, 5];v.rotate_right(2);println!("Rotated right vector: {:?}", v);// Rotated right vector: [4, 5, 1, 2, 3]
}

fill:用指定的值填充整个Vec

fn main() {let mut v = vec![1, 2, 3];v.fill(4);println!("Filled vector: {:?}", v);// Filled vector: [4, 4, 4]
}

fill_with:使用一个闭包生成的值填充整个Vec

fn main() {let mut v = vec![1, 2, 3];v.fill_with(|| 5);println!("Filled with closure vector: {:?}", v);// Filled with closure vector: [5, 5, 5]
}

clone_from_slice:从一个切片克隆元素到Vec中,替换Vec的现有内容

fn main() {let mut v = vec![5, 6];let slice = &[7, 8];v.clone_from_slice(slice);println!("Cloned vector: {:?}", v);// Cloned vector: [7, 8]
}

copy_from_slice:从一个切片复制元素到Vec中,从Vec的特定位置开始覆盖,切片长度和Vec长度必须一样

fn main() {let mut v = vec![1, 2];let slice = &[5, 6];v.copy_from_slice(slice);println!("Copied vector: {:?}", v);// Copied vector: [5, 6]
}

copy_within:将元素从切片的一部分复制到自身的另一部分

fn main() {let mut bytes = *b"Hello, World!";bytes.copy_within(1..5, 8);assert_eq!(&bytes, b"Hello, Wello!");
}

swap_with_slice:将切片与另一个切片交换内容

fn main() {let mut slice1 = [0, 0];let mut slice2 = [1, 2, 3, 4];slice1.swap_with_slice(&mut slice2[2..]);println!("slice1:{:?}", slice1);// slice1:[3, 4]println!("slice2:{:?}", slice2);// slice2:[1, 2, 0, 0]
}

partition_point:在已排序的Vec中找到满足特定谓词的分割点。即返回一个索引,使得在该索引之前的元素满足谓词,在该索引之后的元素不满足谓词

fn main() {let v = vec![1, 2, 3, 4, 5];let partition = v.partition_point(|&x| x < 3);println!("Partition point: {}", partition);// Partition point: 2
}

sort:对Vec中的元素进行排序

fn main() {let mut v = vec![3, 1, 2];v.sort();println!("Sorted vector: {:?}", v);// Sorted vector: [1, 2, 3]
}

sort_by:使用自定义的比较函数对Vec中的元素进行稳定排序

fn main() {let mut v = vec![(3, "c"), (1, "a"), (2, "b")];v.sort_by(|a, b| a.0.cmp(&b.0));println!("Sorted by key vector: {:?}", v);// Sorted by key vector: [(1, "a"), (2, "b"), (3, "c")]
}

sort_by_key:使用自定义的键提取函数对Vec中的元素进行稳定排序

fn main() {let mut v = vec![(3, "c"), (1, "a"), (2, "b")];v.sort_by_key(|&(k, _)| k);println!("Sorted by extracted key vector: {:?}", v);// Sorted by extracted key vector: [(1, "a"), (2, "b"), (3, "c")]
}

sort_by_cached_key:使用自定义的键提取函数对Vec中的元素进行稳定排序,并缓存键以提高性能

fn main() {let mut v = vec![(3, "c"), (1, "a"), (2, "b")];v.sort_by_cached_key(|&(k, _)| k);println!("Sorted by cached key vector: {:?}", v);// Sorted by cached key vector: [(1, "a"), (2, "b"), (3, "c")]
}

to_vec:将一个可转换为向量的类型转换为Vec。通常用于将迭代器、切片等转换为向量

fn main() {let slice = &[1, 2, 3];let v = slice.to_vec();println!("Converted to vector: {:?}", v);// Converted to vector: [1, 2, 3]
}

repeat:创建一个包含重复元素的迭代器。可以与其他方法结合使用,如collect来创建一个包含重复元素的Vec

fn main() {let repeated = (0..5).map(|_| 1).collect::<Vec<_>>();println!("Repeated vector: {:?}", repeated);// Repeated vector: [1, 1, 1, 1, 1]
}

concat:连接多个切片或展平为单个值

fn main() {let s = ["hello", "world"].concat();println!("{}", s);// helloworld
}

join:将向量中的元素用指定的分隔符连接成一个字符串

fn main() {let v = vec!["a", "b", "c"];let joined = v.join(",");println!("Joined string: {}", joined);// Joined string: a,b,c
}

to_ascii_uppercase:将Vec中的所有 ASCII 字符转换为大写。用于将向量中的 ASCII 字符转换为大写形式
to_ascii_lowercase:将Vec中的所有 ASCII 字符转换为小写。前面也有提及,用于将向量中的 ASCII 字符转换为小写形式

fn main() {let original = vec![97, 98, 65, 66, 200];let uppercase_result = original.to_ascii_uppercase();println!("Uppercase result: {:?}", uppercase_result);// Uppercase result: [65, 66, 65, 66, 200]let lowercase_result = original.to_ascii_lowercase();println!("Lowercase result: {:?}", lowercase_result);// Lowercase result: [97, 98, 97, 98, 200]
}
http://www.lryc.cn/news/476221.html

相关文章:

  • 网络原理(初一,TCP/IP五层(或四层)模型面试问题)
  • Unity引擎材质球残留贴图引用的处理
  • Flutter鸿蒙next中封装一个列表组件
  • 层次与网络的视觉对话:树图与力引导布局的双剑合璧
  • python将数据集中所有文件名升序制作txt文件(医学影像)
  • 【The Art of Unit Testing 3_自学笔记06】3.4 + 3.5 单元测试核心技能之:函数式注入与模块化注入的解决方案简介
  • 【VSCode】配置
  • Linux 常用命令整理大全及命令使用心得
  • 计算器的实现
  • 这个工具帮你快速实现数据集成和同步
  • 论文阅读:Computational Long Exposure Mobile Photography (一)
  • 项目解决方案:多地连锁药店高清视频监控系统建设解决方案(设计方案)
  • utf-8、pbkdf2_sha
  • Java之包,抽象类,接口
  • HarmonyOS鸿蒙开发入门,常用ArkUI组件学习(二)
  • 斩!JavaScript语法进阶
  • UFO:Windows操作系统的具象智能代理
  • win10/11无休眠设置和断电后电池模式自动休眠而不是睡眠-用以省电
  • 【动态规划之斐波那契数列模型】——累加递推型动态规划
  • 5g通信系统用到的crc码
  • Ubuntu-22.04 虚拟机安装
  • Windows、Linux系统上进行CPU和内存压力测试
  • FFmpeg 4.3 音视频-多路H265监控录放C++开发八,使用SDLVSQT显示yuv文件 ,使用ffmpeg的AVFrame
  • HTML 标签属性——<a>、<img>、<form>、<input>、<table> 标签属性详解
  • css简写属性
  • 力扣刷题(sql)--零散知识点(2)
  • TCP是怎样工作的网络拥塞控制理论和算法部分记录
  • CSRF初级靶场
  • CSP/信奥赛C++刷题训练:经典差分例题(2):洛谷P9904 :Mieszanie kolorów
  • Java | Leetcode Java题解之第525题连续数组