嗨我在一個相當簡單的測試用例中遇到了生命期問題 我似乎無法理解編譯器告訴我什麼。 下面的代碼粘貼到Rust遊樂場。生命期錯誤我不知道如何解決
關於代碼的想法是,Element
s串在一起成爲一個管道。數據最終會傳遞給下一個元素。每個階段都有一個(rx, tx)
對,它從前一階段接收輸入並將數據發送到下一階段。我可以將Element
標記爲Sync
,因爲只有一個Element
將一次處理一部分數據。
的錯誤是:
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> <anon>:56:18
|
56 | for e in self.elements {
| ^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the body at 53:53...
--> <anon>:53:54
|
53 | pub fn run(&self) -> Vec<thread::JoinHandle<()>> {
| ^
note: ...so that expression is assignable (expected std::vec::Vec<Box<&Element>>, found std::vec::Vec<Box<&'a Element + 'a>>)
--> <anon>:56:18
|
56 | for e in self.elements {
| ^^^^^^^^^^^^^
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that the type `[[email protected]<anon>:62:41: 64:15 e:Box<&Element>, sender:std::sync::Arc<std::sync::Mutex<std::sync::mpsc::SyncSender<(std::string::String, std::string::String)>>>, receiver:std::sync::Arc<std::sync::Mutex<std::sync::mpsc::Receiver<(std::string::String, std::string::String)>>>]` will meet its required lifetime bounds
--> <anon>:62:27
|
62 | handles.push(thread::spawn(move || {
| ^^^^^^^^^^^^^
第一個錯誤我感到困惑,Element
s的定義爲 &'a Element
所以他們不應告訴他們堅持圍繞 沿爲Pipeline
編譯器?
第二個錯誤我想告訴我Vec<thread::JoinHandle<()>>
被告知它取決於終身'a
?但我不確定如何表達。
我希望第三個在我糾正前兩個後會更有意義。目前我只是不知道它告訴我什麼。
use std::sync::{Arc, Mutex};
use std::thread;
use std::result::Result;
use std::sync::mpsc::{SyncSender, Receiver, sync_channel};
pub trait Element: Send + Sync {
fn run(&self, output: Arc<Mutex<SyncSender<i32>>>,
input: Arc<Mutex<Receiver<i32>>>);
}
pub struct TestElement {}
impl TestElement {
pub fn new() -> Self {
TestElement {}
}
}
impl Element for TestElement {
fn run(&self, output: Arc<Mutex<SyncSender<i32>>>,
input: Arc<Mutex<Receiver<i32>>>) {
println!("Hello");
}
}
pub struct Pipeline<'a> {
elements: Vec<Box<&'a Element>>,
}
impl<'a> Pipeline<'a> {
pub fn new(name: String) -> Self {
Pipeline {
elements: Vec::new(),
}
}
pub fn run(&self) -> Vec<thread::JoinHandle<()>> {
let mut handles = Vec::with_capacity(self.elements.len());
for e in self.elements {
let channel = sync_channel::<i32>(1000);
let sender = Arc::new(Mutex::new(channel.0)).clone();
let receiver = Arc::new(Mutex::new(channel.1)).clone();
handles.push(thread::spawn(move || {
e.run(sender, receiver);
}));
}
handles
}
}
fn main() {
let mut test_element = TestElement::new();
let mut pipeline = Pipeline::new("example pipeline".to_string());
let handles = pipeline.run();
}
您是否可以進一步簡化您的代碼?它仍然是一大塊代碼,當我們只處理一小段代碼時,它更容易回答,也更容易理解。謝謝:) –
我試圖縮小一點。我可以減少更多,但這將刪除一些錯誤,我不確定是否應該,因爲我不知道它們是單獨的錯誤還是全部與一個修復相關。你怎麼看 ? –
你爲什麼使用'Box <&'a Element>'? 「Box」已經分配了堆,基本上只是一個指針,因此「Box」應該足夠了。這也可以解決你的一生問題(但照亮其他問題)。還要注意,一個生成的線程可以超越其他的一切,所以'Pipeline :: run()'中產生的線程可以比'Pipeline'對象生存得更長!這不是一個答案,但我希望能夠推動正確的方向。 –