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读作矢量并在其他地方使用数据流。
答案 0 :(得分:1)
问题是你正在向Vec推送借来的价值:&record[i]
。 &
表示借用,因此原始值record
必须比借款人vec
更长。
这似乎很好(两者都在for
体内,因此它们都具有相同的生命周期,即它们都存在于for
体内,因此没有一个比较长寿,但是这个没有发生,因为行input.insert(vec)
正在移动 vec
。这意味着vec
现在由input
拥有,因此它的存在时间与input
一样长(据我所知)。现在,因为input
位于for
正文之外,所以移动的vec
与input
一样长,因此比record[i]
更长。
有一些解决方案,但所有解决方案都试图消除record
和input
之间的依赖关系:
record
是原始值的数组,或实现Copy
特征的东西,则可以省略借用,并将值复制到向量中:vec.push(record[i])
record
值克隆到向量中:vec.push(record[i].clone())
。这会强制创建克隆,如上所述,vec
成为所有者,避免借用。如果record
数组中的元素未实现Copy
或Clone
,则必须移动它。因为值在数组中,所以必须完全移动数组(它不能包含尚未删除的元素)。一种解决方案是将其转换为逐个移出值的迭代器,然后将它们推送到向量中:
for element in record.into_iter().take(13) {
vec.push(element)
}
将record
值替换为其他值。为了仅移动数组的一部分,最后一个解决方案是用其他东西替换数组中的元素。这意味着虽然从数组中删除了一个元素,但是用其他东西替换它,并且该数组仍然有效。
for i in 0..13 {
vec.push(std::mem::replace(&record[i], Default::default()));
}
如果您愿意,可以将Default::default()
替换为其他值。
我希望这会有所帮助。我仍然是Rust的菜鸟,因此接受了对答案的改进和批评:)