2015-06-11 54 views
5

我這裏有這樣的代碼:(Playground link通用FN,渠道和線程產卵

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

但我得到了一生的錯誤,我想不通。

<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); 
           ^~~~ 

有什麼建議嗎?謝謝!

回答

5

錯誤消息建議添加綁定到類型參數T'static。如果你這樣做,它會擺脫的第一個錯誤:

fn run<T: Send + 'static>(task: fn() -> T) -> T 

'static界需要保證通過task返回的值可以活得比的功能,其中task運行。 Read more about the 'static lifetime.

第二個錯誤是您正在傳遞閉包,而run需要函數指針。解決這個問題的方法之一是通過從封閉轉變task到FN:

fn task() -> u32 { 1 + 2 } 

下面是完整的工作代碼:

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); 
} 
+0

這是偉大的,謝謝!我在這裏設法解決了封閉版本:http://is.gd/8UwpjT - 添加''static'總是感覺像一個骯髒的選擇。文檔說,這意味着該項目將持續該計劃的生命。這是不好的做法嗎?什麼時候可以使用靜態生命週期? – jocull

+0

經過一番實驗,我*認爲*我明白了...... http://is.gd/8KWutk「靜態」意味着給定的特質是靜態的 - 不是傳入的項目!這更有意義。 – jocull