你的问题是
.chunks()
不返回已拥有事物的迭代器,它返回一个切片。在这种情况下,这意味着当你有一个
Vec<String>
,
.chunks()
给你一个迭代器
&[String]
,这意味着
url
是a
&String
。然后,您尝试将其关闭
thread::spawn
,但该函数的闭包必须为
'static
这意味着他们不向任何当地人借款。这是错误的来源:传递给的闭包
线程::spawn
间接借款
url_list
.
(旁白:诚然,编译器在引导你到
线程::spawn
调用是问题的根源。
argument requires that "url_list" is borrowed for "'static"
表示它确实知道问题是争论的焦点
线程::spawn
但我不知道为什么它没有明确地突出显示该调用。在我看来,这似乎是编译器诊断中的一个错误。)
请注意,即使您连接了所有线程句柄,这也是有问题的。借款检查器不知道这种情况的发生,也不知道这意味着什么;它只知道关闭
线程::spawn
必须是
'静态
事实并非如此。(即使它知道这一点,线程也会运行
collect_parm_list
在打开结果时可能会感到恐慌
.join()
,这会导致它下降
url_list
然后,在释放bug后,仍在运行的线程就有了用武之地!)
一个简单的解决方案是添加
let url = url.to_owned();
在生成线程之前,这将创建一个独立的副本
url
然后闭合件将捕获该信息。
或者,如果你有办法通知借用检查器,线程不能过期
url_list
即使当前线程出现恐慌
那就安全了。这正是
scoped threads
完成!使用作用域线程可以避免复制
url
,但是
也
让您消除
Arc
从输出列表中选择图层。(你仍然需要
Mutex
以同步访问。)这也允许您使用
.into_inner()
上
静音
当线程完成时,因为您知道此时没有线程仍然可以访问,所以您可以在不等待锁的情况下使用它。
这种方法的代码也变得简单得多:
pub fn collect_parm_list(url_list: Vec<String>) -> Vec<String> {
let id_list = Mutex::new(vec![]);
thread::scope(|s| {
for chunk in url_list.chunks(20) {
for url in chunk {
s.spawn(|| {
// total: optionSale -> result -> total
let mut id_list_v = id_list.lock().unwrap();
id_list_v.push(url.to_string())
});
}
}
});
id_list.into_inner().unwrap()
}