2015-06-11 19 views
5

ho questo codice qui: (Playground link)fn Generico, il canale, e filo uova

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

Ma sto ottenendo un errore di vita che non riesco a capire.

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

Qualche suggerimento? Grazie!

risposta

5

Il messaggio di errore suggerisce di aggiungere un 'static associato al parametro di tipo T. Se si esegue questa operazione, sarà sbarazzarsi del primo errore:

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

Il 'static limite è necessario per garantire che il valore restituito da task può sopravvivere la funzione in cui task piste. Read more about the 'static lifetime.

Il secondo errore è che si passa una chiusura, mentre run si aspetta un puntatore a funzione. Un modo per risolvere questo problema è cambiando task da una chiusura ad un fn:

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

Ecco il codice di lavoro completo:

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

Questo è grande, grazie! Sono riuscito a elaborare anche qui la versione di chiusura: http://is.gd/8UwpjT - L'aggiunta di ''static' sembra sempre una scelta sporca. I documenti dicono che significa che l'oggetto durerà per tutta la vita del programma. Questa cattiva pratica? Quando è accettabile l'uso di vite statiche? – jocull

+0

Dopo alcuni esperimenti, I * think * I get it ... http://is.gd/8KWutk "static" significa che il dato Trait è statico, non l'oggetto che viene passato! Questo ha più senso. – jocull