使用CSV和数据流不够长

时间:2017-07-24 15:10:16

标签: rust

fn main() {
    timely::execute_from_args(std::env::args().skip(0), move |worker| {

        let (mut input, probe) = worker.dataflow::<_, _, _>(|scope| {
            let (input, data) = scope.new_collection();
            let probe = data.inspect(|x| println!("observed data: {:?}", x)).probe();

            (input, probe)
        });

        let mut rdr = csv::ReaderBuilder::new()
            .has_headers(false)
            .flexible(true)
            .delimiter(b'\t')
            .from_reader(io::stdin());

        for result in rdr.deserialize() {
            let record = result.expect("a CSV record");

            let mut vec = Vec::new();
            for i in 0..13 {
                vec.push(&record[i]);

            }

            input.insert(vec);
        }
    });
}

错误是记录不能活得足够长。我尝试读取CSV记录并将其作为矢量读取。然后将记录插入数据流。我可以单独运行它们。我可以将CSv读作矢量并在其他地方使用数据流。

1 个答案:

答案 0 :(得分:1)

问题是你正在向Vec推送借来的价值:&record[i]&表示借用,因此原始值record必须比借款人vec更长。

这似乎很好(两者都在for体内,因此它们都具有相同的生命周期,即它们都存在于for体内,因此没有一个比较长寿,但是这个没有发生,因为行input.insert(vec) 正在移动 vec。这意味着vec现在由input拥有,因此它的存在时间与input一样长(据我所知)。现在,因为input位于for正文之外,所以移动的vecinput一样长,因此比record[i]更长。

有一些解决方案,但所有解决方案都试图消除recordinput之间的依赖关系:

  1. 如果record是原始值的数组,或实现Copy特征的东西,则可以省略借用,并将值复制到向量中:vec.push(record[i])
  2. record值克隆到向量中:vec.push(record[i].clone())。这会强制创建克隆,如上所述,vec成为所有者,避免借用。
  3. 如果record数组中的元素未实现CopyClone,则必须移动它。因为值在数组中,所以必须完全移动数组(它不能包含尚未删除的元素)。一种解决方案是将其转换为逐个移出值的迭代器,然后将它们推送到向量中:

    for element in record.into_iter().take(13) {
        vec.push(element)
    }
    
  4. record值替换为其他值。为了仅移动数组的一部分,最后一个解决方案是用其他东西替换数组中的元素。这意味着虽然从数组中删除了一个元素,但是用其他东西替换它,并且该数组仍然有效。

    for i in 0..13 {
        vec.push(std::mem::replace(&record[i], Default::default()));
    }
    

    如果您愿意,可以将Default::default()替换为其他值。

  5. 我希望这会有所帮助。我仍然是Rust的菜鸟,因此接受了对答案的改进和批评:)