我尝试构建一个简单的类似管道的功能,执行管道的每个阶段都是单独的线程,并将它们与通道传递一起粘合在一起。
Pipe::source(buffer)
.pipe(|input, output| {...})
.pipe(|input, output| {...})
.sink(writer)
我不能为我的生活找出pipe()
函数的函数签名。这是我的代码:
use std::sync::mpsc::channel;
use std::io::{ChanReader,ChanWriter};
use std::thread::Thread;
struct Pipe {
incoming: ChanReader
}
impl Pipe {
fn source(source: &mut Buffer) -> Pipe {
let (tx, rx) = channel();
let reader = ChanReader::new(rx);
let mut writer = ChanWriter::new(tx);
loop {
match source.read_char() {
Ok(c) => writer.write_char(c),
Err(_) => break
};
};
Pipe { incoming: reader }
}
fn sink(&mut self, sink: &mut Writer) {
loop {
match self.incoming.read_char() {
Ok(c) => sink.write_char(c),
Err(_) => break
};
};
}
fn pipe(&self, transform: Box<Fn(&mut ChanReader, &mut ChanWriter)+Send>) -> Pipe {
let (tx, rx) = channel();
let reader = ChanReader::new(rx);
let mut writer = ChanWriter::new(tx);
Thread::spawn(move || {
transform(&self.incoming, &writer);
});
Pipe { incoming: reader }
}
}
编译错误:
src/lib.rs:39:28: 41:10 error: cannot infer an appropriate lifetime due to conflicting requirements
src/lib.rs:39 Thread::spawn(move || {
src/lib.rs:40 transform(&self.incoming, &writer);
src/lib.rs:41 });
src/lib.rs:39:9: 39:22 note: first, the lifetime cannot outlive the expression at 39:8...
src/lib.rs:39 Thread::spawn(move || {
^~~~~~~~~~~~~
src/lib.rs:39:9: 39:22 note: ...so that the declared lifetime parameter bounds are satisfied
src/lib.rs:39 Thread::spawn(move || {
^~~~~~~~~~~~~
src/lib.rs:39:9: 41:11 note: but, the lifetime must be valid for the call at 39:8...
src/lib.rs:39 Thread::spawn(move || {
src/lib.rs:40 transform(&self.incoming, &writer);
src/lib.rs:41 });
src/lib.rs:39:28: 41:10 note: ...so that argument is valid for the call
src/lib.rs:39 Thread::spawn(move || {
src/lib.rs:40 transform(&self.incoming, &writer);
src/lib.rs:41 });
src/lib.rs:39:9: 39:22 error: declared lifetime bound not satisfied
src/lib.rs:39 Thread::spawn(move || {
^~~~~~~~~~~~~
src/lib.rs:34:87: 44:6 note: lifetime parameter instantiated with the anonymous lifetime #1 defined on the block at 34:86
src/lib.rs:34 fn pipe(&self, transform: Box<Fn(&mut ChanReader, &mut ChanWriter)+Send>) -> Pipe {
src/lib.rs:35 let (tx, rx) = channel();
src/lib.rs:36 let reader = ChanReader::new(rx);
src/lib.rs:37 let mut writer = ChanWriter::new(tx);
src/lib.rs:38
src/lib.rs:39 Thread::spawn(move || {
...
note: but lifetime parameter must outlive the static lifetime
error: aborting due to 2 previous errors
Could not compile `pipes`.
我正在使用1.0.0-dev
。
答案 0 :(得分:2)
Thread::spawn
要求提供给它的函数为'static
;因此,封闭必须消耗所有进入它的东西。您已经引用了self.incoming
- 一个非静态引用。这不起作用;你必须将读者移入其中。这样做的方法可能是在方法self
中使用pipe
,而不是通过引用来使用它:
fn pipe<F: FnOnce(&mut ChanReader, &mut ChanWriter) + Send>(mut self, transform: F) -> Pipe {
let (tx, rx) = channel();
let reader = ChanReader::new(rx);
let mut writer = ChanWriter::new(tx);
Thread::spawn(move || {
transform(&mut self.incoming, &mut writer);
});
Pipe { incoming: reader }
}
现在,self
和writer
被移入生成的线程,一切都很花哨。
(为了更好的衡量,我将你的封包拆开,因为它没有理由将它装箱并将其改为FnOnce
以获得最大的表现力。)