我使用Kuchiki解析一些HTML并使用hyper发出HTTP请求,以便通过scoped_threadpool同时对结果进行操作。
我选择并迭代列表。我根据列表的数量决定在线程池中分配的线程数:
let listings = document.select("table.listings").unwrap();
let mut pool = Pool::new(listings.count() as u32);
pool.scoped(|scope| {
for listing in listings {
do_stuff_with(listing);
}
});
当我尝试这样做时,我得到capture of moved value: listings
。 listings
是kuchiki::iter::Select<kuchiki::iter::Elements<kuchiki::iter::Descendants>>
,这是不可复制的 - 所以我既没有隐式克隆也没有明确的.clone
。
在游泳池内,我可以再次document.select("table.listings")
,它会起作用,但这对我来说似乎没用,因为我已经用它来计算。循环后我也不需要listings
。
我有什么方法可以在闭包中使用不可复制的值吗?
答案 0 :(得分:3)
可悲的是,我认为它不可能以你想要的方式实现。
您的listings.count()
使用了迭代器listings
。您可以通过编写listings.by_ref().count()
来避免这种情况,但这不会产生预期的效果,因为count()
将使用迭代器的所有元素,因此下一次调用next()
将会总是收益None
。
实现目标的唯一方法是以某种方式获取迭代器listings
的长度而不消耗其元素。特征ExactSizeIterator
是为此目的而构建的,但似乎kuchiki::iter::Select
没有实现它。请注意,对于那种迭代器,这也可能是不可能的。
编辑:正如@delnan建议的那样,另一种可能性当然是将迭代器收集到Vec
中。这有一些缺点,但在你的情况下可能是一个好主意。
我还要注意,您可能不应该为SELECT
结果集中的每一行创建一个线程。通常,线程池使用与CPU相同的线程数。