gpt4 book ai didi

csv - 如何在不复制的情况下在 Rust 中迭代 Vec 时分配切片?

转载 作者:行者123 更新时间:2023-11-29 07:54:35 25 4
gpt4 key购买 nike

我正在尝试逐行有效地解析 CSV 文件,而无需分配不必要的内存。

因为我们不能在 Rust 中索引字符串,我的想法是为每一行创建一个结构,它拥有一个自有的 Vec<char>。行字符和几个 &[char]表示该 Vec 中位置的切片需要进一步处理的字段。

我只支持英语,所以不需要 Unicode 字素。

我从 BufReader 中抓取每一行,收进我的Vec<char>然后遍历字符以注意每个字段切片的正确偏移量:

let mut r_line: String;
let mut char_count: usize;
let mut comma_count: usize;
let mut payload_start: usize;
for stored in &ms7_files {
let reader = BufReader::new(File::open(&stored.as_path()).unwrap());
for line in reader.lines() {
r_line = line.unwrap().to_string();
let r_chars: Vec<char> = r_line.chars().collect();
char_count = 0;
comma_count = 0;
payload_start = 0;
for chara in r_chars {
char_count += 1;
if chara == ',' {
comma_count += 1;
if comma_count == 1 {
let r_itemid = &r_chars[0..char_count - 1];
payload_start = char_count + 1;
} else if comma_count == 2 {
let r_date = &r_chars[payload_start..char_count - 1];
let r_payload = & r_chars[payload_start..r_line.len() - 1];
}
}
}
// Code omitted here to initialize a struct described in my
// text above and add it to a Vec for later processing
}
}

一切顺利,直到里面的代码if测试 comma_count我尝试在 Vec 中创建 char 切片.当我尝试编译时,我遇到了可怕的事情:

proc_sales.rs:87:23: 87:30 error: use of moved value: `r_chars` [E0382]
proc_sales.rs:87 let r_itemid = &r_chars[0..char_count - 1];
^~~~~~
proc_sales.rs:87:23: 87:30 help: run `rustc --explain E0382` to see a detailed explanation
proc_sales.rs:82:17: 82:24 note: `r_chars` moved here because it has type `collections::vec::Vec<char>`, which is non-copyable
proc_sales.rs:82 for chara in r_chars {
^~~~~~~

对于创建切片的每一次尝试。我基本上可以理解为什么编译器会提示。我想弄清楚的是一种更好的策略来收集和处理这些数据,而无需诉诸大量复制和克隆。哎呀,如果我能留下原来的 String (对于每个文件行)由 BufReader 拥有坚持下去,我愿意!

请随意评论修复上述代码,以及针对此问题的替代方法的建议,以限制不必要的复制。

最佳答案

BufReader::lines 返回产生 Result<String> 的迭代器项目。当unwrap在这样的项目上调用它总是会分配一个新的 String (请注意,在 line.unwrap().to_string() 中,to_string() 是多余的)。

如果你想最小化分配,你可以使用 BufReader::read_line .

要拆分 CSV 行的字段,您可以使用 str::split .

这是您的代码的简化版本:

use std::io::{BufRead, BufReader};
use std::fs::File;

fn main() {
let mut line = String::new();
let ms7_files = ["file1.cvs", "file2.cvs"];
for stored in &ms7_files {
let mut reader = BufReader::new(File::open(stored).unwrap());
while reader.read_line(&mut line).unwrap() > 0 {
// creates a scope to the iterator, so we can call line.clear()
{
// does not allocate
let mut it = line.split(',');
// item_id, date and payload are string slices, that is &str
let item_id = it.next().expect("no item_id fied");
let date = it.next().expect("no date field");
let payload = it.next().expect("no payload field");
// process fields
}
// sets len of line to 0, but does not deallocate
line.clear()
}
}
}

您可能还想看看 various crates 以处理 CSV 文件。

关于csv - 如何在不复制的情况下在 Rust 中迭代 Vec 时分配切片?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37290216/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com