2015-06-11 2 views
5

У меня есть этот код здесь: (Playground link)Generic сноска, канал, и поток икра

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

Сообщение об ошибке предлагает добавить 'static к параметру типа T. Если вы сделаете это, он избавится от первой ошибки:

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 '' static' означает, что данный Trait статичен - не передается элемент! Это имеет смысл. – jocull