嗨我在一个相当简单的测试用例中遇到了生命期问题 我似乎无法理解编译器告诉我什么。 下面的代码粘贴到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'对象生存得更长!这不是一个答案,但我希望能够推动正确的方向。 –