[英]Cannot infer an appropriate lifetime for lifetime parameter cloning trait object
The duplicates of this question don't seem to solve things for me. 这个问题的重复似乎并没有为我解决问题。 The following code gives me errors: 以下代码给出了错误:
use std::collections::HashMap;
use std::thread;
pub trait Spider : Sync + Send {
fn add_request_headers(&self, headers: &mut Vec<String>);
}
pub struct Google {}
impl Spider for Google {
fn add_request_headers(&self, headers: &mut Vec<String>) {
headers.push("Hello".to_string())
}
}
fn parallel_get(spiders: &HashMap<String, Box<Spider>>) -> std::thread::JoinHandle<()> {
let thread_spiders = spiders.clone();
thread::spawn(move || {
let headers = &mut vec![];
let spider = thread_spiders.get("Google").unwrap();
spider.add_request_headers(headers);
})
}
fn main() {
let spiders = HashMap::new();
let spider = Box::new(Google{});
spiders.insert("Google", spider);
}
Run on the playground here . 在这里的操场上跑步。
I get: 我明白了:
rustc 1.14.0 (e8a012324 2016-12-16)
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
--> <anon>:18:34
|
18 | let thread_spiders = spiders.clone();
| ^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the block at 17:87...
--> <anon>:17:88
|
17 | fn parallel_get(spiders: &HashMap<String, Box<Spider>>) -> std::thread::JoinHandle<()> {
| ^
note: ...so that types are compatible (expected &&std::collections::HashMap<std::string::String, Box<Spider>>, found &&std::collections::HashMap<std::string::String, Box<Spider + 'static>>)
--> <anon>:18:34
|
18 | let thread_spiders = spiders.clone();
| ^^^^^
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that the type `[closure@<anon>:19:19: 23:6 thread_spiders:&std::collections::HashMap<std::string::String, Box<Spider>>]` will meet its required lifetime bounds
--> <anon>:19:5
|
19 | thread::spawn(move || {
| ^^^^^^^^^^^^^
I think it's telling me that it can't automatically infer the lifetime of thread_spiders
because it needs to be 'static
to live long enough for the thread, but it can't outlive 'a
which is the lifetime of the input parameter. 我认为它告诉我它不能自动推断thread_spiders
的生命周期,因为它需要'static
才能为线程保持足够长的时间,但它不能超过'a
这是输入参数的生命周期。
The thing is, I can clone other objects in parallel_get
and they get moved into the new thread without issue. 问题是,我可以在parallel_get
克隆其他对象,并且它们可以毫无问题地移动到新线程中。 But for some reason thread_spiders
seems to trip up the compiler. 但由于某种原因, thread_spiders
似乎绊倒了编译器。 It should have a lifetime of 'a
if I'm correct and then get moved into the thread closure. 它应该具有'a
的生命周期,如果我是正确的,然后进入线程闭包。
I've tried adding explicit lifetime parameters to parallel_get
but haven't been able to get anything working. 我已经尝试将明确的生命周期参数添加到parallel_get
但是无法获得任何工作。 How can I make this code compile? 如何编译此代码?
The error message is quite confusing in this case, but notice a double ampersand here: (expected &&std::collections::HashMap<std::string::String, Box<Spider>>, found &&std::collections::HashMap<std::string::String, Box<Spider + 'static>>)
. 在这种情况下错误消息非常混乱,但请注意这里的双符号:( (expected &&std::collections::HashMap<std::string::String, Box<Spider>>, found &&std::collections::HashMap<std::string::String, Box<Spider + 'static>>)
。
It looks like it tries to clone the reference. 看起来它试图克隆引用。 I assume you wanted to clone the entire HashMap
. 我假设您想要克隆整个HashMap
。 Calling clone
explicitly as Clone::clone(spiders)
gives much clearer error message: 将clone
显式调用为Clone::clone(spiders)
提供更清晰的错误消息:
error[E0277]: the trait bound `Spider: std::clone::Clone` is not satisfied
error[E0277]: the trait bound `Spider: std::marker::Sized` is not satisfied
--> error_orig.rs:19:26
|
19 | let thread_spiders = Clone::clone(spiders);
| ^^^^^^^^^^^^ the trait `std::marker::Sized` is not implemented for `Spider`
|
= note: `Spider` does not have a constant size known at compile-time
= note: required because of the requirements on the impl of `std::clone::Clone` for `Box<Spider>`
= note: required because of the requirements on the impl of `std::clone::Clone` for `std::collections::HashMap<std::string::String, Box<Spider>>`
= note: required by `std::clone::Clone::clone`
You are calling Clone::clone
on Box<Spider>
, an owned trait object. 你在Box<Spider>
上调用Clone::clone
,这是一个拥有的特征对象。 How do I clone a HashMap containing a boxed trait object? 如何克隆包含盒装特征对象的HashMap? illustrates that it can be implemented by introducing a cloning method to your trait, like so: 说明它可以通过向您的特征引入克隆方法来实现,如下所示:
pub trait Spider: Sync + Send {
fn add_request_headers(&self, headers: &mut Vec<String>);
fn clone_into_box(&self) -> Box<Spider>;
}
impl Clone for Box<Spider> {
fn clone(&self) -> Self {
self.clone_into_box()
}
}
#[derive(Clone)]
pub struct Google {}
impl Spider for Google {
fn add_request_headers(&self, headers: &mut Vec<String>) {
headers.push("Hello".to_string())
}
fn clone_into_box(&self) -> Box<Spider> {
Box::new(self.clone())
}
}
How to clone a struct storing a trait object? 如何克隆存储特征对象的结构? suggests creating a separate trait for this polymorphic cloning method. 建议为这种多态克隆方法创建一个单独的特征。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.