首页 文章

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

提问于
浏览
4

这个问题的重复似乎并没有为我解决问题 . 以下代码给出了错误:

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);
}

在操场上跑步here .

我明白了:

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 || {
   |     ^^^^^^^^^^^^^

我认为's telling me that it can' t会自动推断 thread_spiders 的生命周期,因为它需要 'static 才能为线程提供足够长的时间,但它不能超过 'a 这是输入参数的生命周期 .

问题是,我可以克隆 parallel_get 中的其他对象,并且它们会毫无问题地进入新线程 . 但出于某种原因 thread_spiders 似乎绊倒了编译器 . 它应该具有 'a 的生命周期,如果我是正确的,然后进入线程闭包 .

我已经尝试将显式生命周期参数添加到 parallel_get 但是无法获得任何工作 . 如何编译此代码?

1 回答

  • -1

    在这种情况下,错误消息非常混乱,但请注意这里的双符号: (expected &&std::collections::HashMap<std::string::String, Box<Spider>>, found &&std::collections::HashMap<std::string::String, Box<Spider + 'static>>) .

    看起来它试图克隆引用 . 我假设您想克隆整个 HashMap . 显式调用 cloneClone::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`
    

    您在 Box<Spider> 上调用 Clone::clone ,这是一个拥有的特征对象 . How do I clone a HashMap containing a boxed trait object?说明可以通过向您的特征引入克隆方法来实现它,如下所示:

    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?建议为这种多态克隆方法创建一个单独的特征 .

相关问题