2016-12-31 40 views
3

此問題的重複似乎無法爲我解決問題。下面的代碼給我的錯誤:在操場上here無法推斷生命期參數克隆特徵對象的適當生命期

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

運行。

我得到:

rustc 1.14.0 (e8a-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 `[[email protected]<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 || { 
    |  ^^^^^^^^^^^^^ 

我認爲它告訴我,因爲它需要'static足夠長住它的線程不能自動推斷thread_spiders壽命,但它不能活得長'a這是輸入參數的生命週期。

問題是,我可以在parallel_get中克隆其他對象,並且它們可以毫無問題地移入新線程。但由於某種原因thread_spiders似乎絆倒了編譯器。如果我是正確的,它應該有一個'a的生命週期,然後進入線程關閉。

我試過在parallel_get中添加明確的生命週期參數,但一直未能得到任何工作。我怎樣才能讓這段代碼編譯?

+0

請**鏈接到**您已閱讀並認定爲無幫助的副本,否則我們可能會在回答您的問題時重複這些副本,然後無人幫助。 – Shepmaster

+0

例如,[如何克隆包含盒裝特質對象的HashMap?](http://stackoverflow.com/q/39120183/155423)似乎與您的實際代碼非常接近。 – Shepmaster

回答

-1

在這種情況下,錯誤消息相當混亂,但請注意這裏有一個雙「&」符號: (expected &&std::collections::HashMap<std::string::String, Box<Spider>>, found &&std::collections::HashMap<std::string::String, Box<Spider + 'static>>)

它看起來像試圖克隆參考。我假設你想克隆整個HashMap。調用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` 

您正在呼籲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?建議創建用於該多態克隆方法分離的性狀。