rust - 如何告诉借用检查器清除的 Vec 不包含借用?
问题描述
我正在处理一个庞大的 TSV(制表符分隔值)文件,并希望尽可能高效地执行此操作。为此,我想我会Vec
通过在循环之前预先分配它来防止为每一行分配一个新的:
let mut line = String::new();
let mut fields = Vec::with_capacity(headers.len());
while reader.read_line(&mut line)? > 0 {
fields.extend(line.split('\t'));
// do something with fields
fields.clear();
}
自然地,借用检查器不会被逗乐,因为我们正在覆盖line
而fields
可能仍然有对它的引用:
error[E0502]: cannot borrow `line` as mutable because it is also borrowed as immutable
--> src/main.rs:66:28
|
66 | while reader.read_line(&mut line)? > 0 {
| ^^^^^^^^^ mutable borrow occurs here
67 | fields.extend(line.split('\t'));
| ------ ---- immutable borrow occurs here
| |
| immutable borrow later used here
(游乐场)
这实际上不是问题,因为fields.clear();
删除了所有引用,因此在循环开始时read_line(&mut line)
调用时,fields
实际上并没有从line
.
但是我如何通知借阅检查员呢?
解决方案
您的问题与本文中描述的问题相似。
除了那里的答案(生命周期转换、参考单元)之外,根据您注释掉的复杂操作,您可能根本不需要存储对的引用line
。例如,考虑以下对 Playground 代码的修改:
use std::io::BufRead;
fn main() -> Result<(), std::io::Error> {
let headers = vec![1,2,3,4];
let mut reader = std::io::BufReader::new(std::fs::File::open("foo.txt")?);
let mut fields = Vec::with_capacity(headers.len());
loop {
let mut line = String::new();
if reader.read_line(&mut line)? == 0 {
break;
}
fields.push(0);
fields.extend(line.match_indices('\t').map(|x| x.0 + 1));
// do something with fields
// each element of fields starts a field; you can use the next
// element of fields to find the end of the field.
// (make sure to account for the \t, and the last field having no
// 'next' element in fields.
fields.clear();
}
Ok(())
}
推荐阅读
- css - 带有脚手架 EF 核心页面的引导程序 - 即使使用内联 CSS 自动换行样式,文本也不会在文本框内换行
- tensorflow - 神经网络超参数调整 - 设置随机种子是个好主意吗?
- ruby-on-rails - 运行 docker-compose “'时出错:没有这样的文件或目录'不执行'sh”
- node.js - 猫鼬_id到unit64
- nestjs - NestJS Nest 无法解析 UsersService 的依赖关系
- python - QuerySet 没有 field_names?
- sql - try_cast 和 cast 不同的结果。将日期数据类型转换为日期时间数据类型导致值超出范围
- sql-server - 学习如何使用 SQL Server 游标获取数据库中所有列和表的列表,其中列的最长数据长度使用 MAX(LEN)
- python - 空中碰撞
- java - 使用不同模块进行 log4j 日志记录