Rust可变向量扫描库vec_mut_scan的使用:高效遍历与修改可变向量元素的Rust工具
vec_mut_scan
支持突变和项移除的向量前向扫描。
为 Vec
提供了一个 VecMutScan
包装器,具有类似迭代器的接口,同时允许突变和移除项。项保持顺序,即使项被移除,每个项最多移动一次。在迭代过程中丢弃 VecMutScan
会保留向量中剩余的项。
这可以看作是 Vec
的 retain
和 drain
的扩展。它也与不稳定的 drain_filter
非常相似,但稍微更灵活。与 drain_filter
不同,这指定了丢弃行为(保留所有后续元素)。它也不要求在闭包内完成过滤,这提供了额外的灵活性,但代价是无法实现 Iterator
特性。
还提供了一个 VecGrowScan
包装器,扩展了 VecMutScan
以允许在迭代期间插入。这可能需要额外的项移动和临时存储,但仍然在线性时间内运行。
许可证
本软件根据零条款 BSD 许可证提供,请参阅 COPYRIGHT 获取完整的许可信息和此许可证的例外情况。
贡献
除非您明确声明,否则您有意提交包含在此软件中的任何贡献均应按照 COPYRIGHT 中定义的许可进行许可。
元数据
包 URL: pkg:cargo/vec_mut_scan@0.5.0
发布时间: 超过 2 年前
最低 Rust 版本: v1.36.0
许可证: 0BSD
大小: 9.11 KiB
安装
在项目目录中运行以下 Cargo 命令:
cargo add vec_mut_scan
或者将以下行添加到您的 Cargo.toml:
vec_mut_scan = "0.5.0"
文档
仓库
所有者
- Jannis Harder (jix)
分类
- 数据结构
- 无标准库
- 算法
完整示例代码
use vec_mut_scan::VecMutScan;
fn main() {
// 创建一个包含整数的向量
let mut vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// 创建 VecMutScan 包装器
let mut scan = VecMutScan::new(&mut vec);
// 遍历并修改元素
while let Some(item) = scan.next() {
// 将偶数乘以 2
if *item % 2 == 0 {
*item *= 2;
}
// 移除能被 3 整除的元素
if *item % 3 == 0 {
scan.remove();
}
}
// 输出结果
println!("处理后的向量: {:?}", vec);
}
use vec_mut_scan::VecGrowScan;
fn main() {
// 创建一个包含整数的向量
let mut vec = vec![1, 2, 3, 4, 5];
// 创建 VecGrowScan 包装器
let mut scan = VecGrowScan::new(&mut vec);
// 遍历、修改和插入元素
while let Some(item) = scan.next() {
// 在偶数后插入新元素
if *item % 2 == 0 {
scan.insert_after(*item * 10);
}
// 在特定值前插入元素
if *item == 3 {
scan.insert_before(99);
}
}
// 输出结果
println!("处理后的向量: {:?}", vec);
}
use vec_mut_scan::VecMutScan;
fn main() {
// 处理字符串向量
let mut words = vec!["hello", "world", "rust", "programming", "language"];
let mut scan = VecMutScan::new(&mut words);
// 修改和过滤字符串
while let Some(word) = scan.next() {
// 将短字符串转换为大写
if word.len() < 5 {
*word = word.to_uppercase().as_str();
}
// 移除包含特定字符的单词
if word.contains('r') {
scan.remove();
}
}
println!("处理后的单词: {:?}", words);
}
vec_mut_scan:高效遍历与修改可变向量元素的Rust工具
简介
vec_mut_scan是一个专为Rust设计的可变向量扫描库,它提供了高效的方法来遍历和修改可变向量(Vec<T>)中的元素。该库特别适用于需要在遍历过程中同时修改向量元素的场景,避免了传统迭代器可能带来的借用检查器冲突。
主要特性
- 安全的可变遍历:允许在遍历过程中修改向量元素
- 高性能:采用底层指针操作,避免不必要的开销
- 简洁API:提供直观易用的接口
- 零依赖:纯Rust实现,无外部依赖
安装方法
在Cargo.toml中添加依赖:
[dependencies]
vec_mut_scan = "0.1.0"
基本用法
简单示例
use vec_mut_scan::VecMutScan;
fn main() {
let mut vec = vec![1, 2, 3, 4, 5];
// 创建可变扫描器
let mut scanner = VecMutScan::new(&mut vec);
// 遍历并修改元素
while let Some(element) = scanner.next() {
*element *= 2; // 将每个元素乘以2
}
assert_eq!(vec, [2, 4, 6, 8, 10]);
}
带索引的遍历
use vec_mut_scan::VecMutScan;
fn main() {
let mut vec = vec!["a", "b", "c", "d"];
let mut scanner = VecMutScan::new(&mut vec);
while let Some((index, element)) = scanner.next_with_index() {
*element = match index {
0 => "first",
1 => "second",
2 => "third",
_ => "other"
};
}
assert_eq!(vec, ["first", "second", "third", "other"]);
}
条件修改示例
use vec_mut_scan::VecMutScan;
fn main() {
let mut numbers = vec![1, -2, 3, -4, 5];
let mut scanner = VecMutScan::new(&mut numbers);
while let Some(num) = scanner.next() {
if *num < 0 {
*num = 0; // 将所有负数替换为0
}
}
assert_eq!(numbers, [1, 0, 3, 0, 5]);
}
高级用法
跳过元素
use vec_mut_scan::VecMutScan;
fn main() {
let mut vec = vec![1, 2, 3, 4, 5];
let mut scanner = VecMutScan::new(&mut vec);
// 跳过前两个元素
scanner.skip(2);
while let Some(element) = scanner.next() {
*element += 10;
}
assert_eq!(vec, [1, 2, 13, 14, 15]);
}
重置扫描器
use vec_mut_scan::VecMutScan;
fn main() {
let mut vec = vec![1, 2, 3];
let mut scanner = VecMutScan::new(&mut vec);
// 第一次遍历
while let Some(element) = scanner.next() {
*element += 1;
}
// 重置扫描器重新开始
scanner.reset();
// 第二次遍历
while let Some(element) = scanner.next() {
*element *= 2;
}
assert_eq!(vec, [4, 6, 8]); // (1+1)*2=4, (2+1)*2=6, (3+1)*2=8
}
完整示例demo
use vec_mut_scan::VecMutScan;
fn main() {
// 示例1: 基本数值操作
println!("=== 基本数值操作示例 ===");
let mut numbers = vec![10, 20, 30, 40, 50];
let mut scanner = VecMutScan::new(&mut numbers);
while let Some(num) = scanner.next() {
*num += 5; // 每个元素加5
}
println!("加5后的结果: {:?}", numbers);
// 示例2: 字符串处理
println!("\n=== 字符串处理示例 ===");
let mut words = vec!["hello", "world", "rust", "programming"];
let mut word_scanner = VecMutScan::new(&mut words);
while let Some((index, word)) = word_scanner.next_with_index() {
*word = match index {
0 => "HELLO",
1 => "WORLD",
2 => "RUST",
_ => "PROGRAMMING"
};
}
println!("处理后的字符串: {:?}", words);
// 示例3: 条件过滤和修改
println!("\n=== 条件过滤示例 ===");
let mut scores = vec![85, 92, 78, 60, 95, 88];
let mut score_scanner = VecMutScan::new(&mut scores);
while let Some(score) = score_scanner.next() {
if *score < 80 {
*score = 80; // 将低于80分的分数提升到80分
}
}
println!("调整后的分数: {:?}", scores);
// 示例4: 高级用法组合
println!("\n=== 高级用法组合示例 ===");
let mut data = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let mut data_scanner = VecMutScan::new(&mut data);
// 跳过前3个元素
data_scanner.skip(3);
// 修改剩余元素
while let Some(element) = data_scanner.next() {
*element *= 10;
}
println!("跳过前3个元素后的结果: {:?}", data);
// 重置扫描器并重新处理
data_scanner.reset();
while let Some(element) = data_scanner.next() {
*element += 1;
}
println!("重置后再次处理的结果: {:?}", data);
}
#[test]
fn test_vec_mut_scan() {
// 测试基本功能
let mut test_vec = vec![1, 2, 3];
let mut test_scanner = VecMutScan::new(&mut test_vec);
while let Some(element) = test_scanner.next() {
*element *= 2;
}
assert_eq!(test_vec, [2, 4, 6]);
println!("测试通过!");
}
注意事项
- 在遍历过程中不要对原始向量进行push/pop操作,这会导致未定义行为
- 扫描器在遍历期间会持有向量的可变引用
- 适用于需要高性能修改大量元素的场景
性能建议
- 对于大型向量,vec_mut_scan比传统的iter_mut().enumerate()更高效
- 避免在循环中创建新的扫描器实例
- 考虑批量处理来减少函数调用开销
这个库为需要高效遍历和修改可变向量的Rust开发者提供了一个安全且高性能的解决方案。