然后在线程中执行的传入函数的生命周期

Lifetime for passed-in function that is then executed in a thread

我正在尝试构建一个简单的类似管道的功能,它执行管道的每个阶段都是单独的线程,并通过通道传递将它们粘合在一起。

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

Thread::spawn要求给它的函数是'static;因此,闭包必须消耗所有进入其中的东西。您已经引用了 self.incoming——一个非静态引用。这行不通;您必须将 reader 移入其中。这样做的方法可能是在方法 pipe 中使用 self 而不是引用它:

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

现在,selfwriter 被移动到生成的线程中,一切都很好。

(为了更好的衡量,我拆开了你的闭包,因为没有理由将它装箱并将其更改为 FnOnce 以获得最大的表现力。)