通用fn,通道和线程生成

joc*_*ull 5 closures lifetime rust

我在这里有这个代码:( 游乐场链接)

use std::thread;
use std::sync::mpsc::channel;

fn run<T: Send>(task: fn() -> T) -> T {
    let (tx, rx) = channel();
    thread::spawn(move || {
        tx.send(task());
    });
    rx.recv().unwrap()
}

fn main() {
    let task = || 1 + 2;

    let result = run(task);

    println!("{}", result);
}
Run Code Online (Sandbox Code Playgroud)

但是我得到了一个我无法弄清楚的终生错误.

<anon>:6:5: 6:18 error: the parameter type `T` may not live long enough [E0310]
<anon>:6     thread::spawn(move || {
             ^~~~~~~~~~~~~
<anon>:6:5: 6:18 help: consider adding an explicit lifetime bound `T: 'static`...
<anon>:6:5: 6:18 note: ...so that captured variable `tx` does not outlive the enclosing closure
<anon>:6     thread::spawn(move || {
             ^~~~~~~~~~~~~
<anon>:15:22: 15:26 error: mismatched types:
 expected `fn() -> _`,
    found `[closure <anon>:13:16: 13:24]`
(expected fn pointer,
    found closure) [E0308]
<anon>:15     let result = run(task);
                               ^~~~
Run Code Online (Sandbox Code Playgroud)

有什么建议?谢谢!

小智 5

错误消息建议'static在type参数中添加绑定T.如果你这样做,它将摆脱第一个错误:

fn run<T: Send + 'static>(task: fn() -> T) -> T
Run Code Online (Sandbox Code Playgroud)

'static绑定需要保证返回的值task可以活得比其中函数task运行. 阅读有关'static生命的更多信息.

第二个错误是你传递一个闭包,同时run需要一个函数指针.解决这个问题的一种方法是task从闭包更改为fn:

    fn task() -> u32 { 1 + 2 }
Run Code Online (Sandbox Code Playgroud)

这是完整的工作代码:

use std::thread;
use std::sync::mpsc::channel;

fn run<T: Send + 'static>(task: fn() -> T) -> T {
    let (tx, rx) = channel();
    thread::spawn(move || {
        tx.send(task());
    });
    rx.recv().unwrap()
}

fn main() {
    fn task() -> u32 { 1 + 2 }
    let result = run(task);
    println!("{}", result);
}
Run Code Online (Sandbox Code Playgroud)