简体   繁体   English

无法推断生命周期参数克隆特征对象的适当生命周期

[英]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.

相关问题 在实现Deref特征时无法推断生命周期参数的适当生命周期 - Cannot infer an appropriate lifetime for lifetime parameter while implementing Deref trait 将结构转换为具有生存期的特征得到“由于需求冲突,无法为生存期参数&#39;a&#39;推断适当的生存期” - casting struct to trait with lifetime got “cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements” 无法推断出合适的生命周期 - cannot infer an appropriate lifetime for lifetime Rust – 从 trait 方法返回 trait 对象时无法推断出适当的生命周期 - Rust – cannot infer an appropriate lifetime when returning trait object from trait method 无法为结构内具有相同生命周期的多个引用推断生命参数的适当生命周期 [E0495] - cannot infer an appropriate lifetime for lifetime parameter with multiple references with the same lifetime inside a struct [E0495] 作为函数参数的闭包“由于需求冲突而无法推断出适当的寿命” - Closure as function parameter “cannot infer an appropriate lifetime due to conflicting requirements” 由于对由具有 Serde Deserialize 的枚举组成的结构的要求相互冲突,因此无法为生命周期参数“de”推断合适的生命周期 - cannot infer an appropriate lifetime for lifetime parameter `'de` due to conflicting requirements for struct made of enums with Serde Deserialize "由于要求冲突,无法推断函数调用中生命周期参数 &#39;_ 的适当生命周期" - cannot infer an appropriate lifetime for lifetime parameter '_ in function call due to conflicting requirements 调用 lambda 时“无法推断出适当的生命周期” - “Cannot infer an appropriate lifetime” when calling lambda 在结构中存储闭包 - 无法推断出适当的寿命 - Storing a closure in a structure — cannot infer an appropriate lifetime
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM