0

我正在使用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. listingsis kuchiki::iter::Select<kuchiki::iter::Elements<kuchiki::iter::Descendants>>,这是不可复制的——所以我既没有得到隐式克隆也没有得到显式.clone.

在池中,我可以再做document.select("table.listings")一次,它会起作用,但这对我来说似乎没有必要,因为我已经用它来获得计数。我也不需要listings在循环之后。

我有什么办法可以在闭包中使用不可复制的值吗?

4

1 回答 1

4

可悲的是,我认为这不可能按照您想要的方式进行。

listings.count()使用迭代器listings。您可以通过编写来避免这种情况listings.by_ref().count(),但这不会产生预期的效果,因为count()会消耗迭代器的所有元素,因此下一次调用next()将始终 yield None

实现目标的唯一方法是以某种方式获取迭代器的长度listings而不消耗其元素。该特征ExactSizeIterator是为此目的而构建的,但似乎kuchiki::iter::Select没有实现它。请注意,对于那种迭代器,这也可能是不可能的。

编辑:正如@delnan 建议的那样,另一种可能性当然是将迭代器收集到Vec. 这有一些缺点,但在您的情况下可能是一个好主意。


我还要注意,您可能不应该为SELECT结果集中的每一行创建一个线程。通常,线程池使用的线程数大约与 CPU 的数量一样多。

于 2016-02-27T17:13:53.280 回答