2015-06-11 14 views
5

tôi có mã này ở đây: (Playground link)Generic fn, kênh, và chủ đề spawn

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

Nhưng tôi nhận được một lỗi đời tôi không thể tìm ra.

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

Mọi đề xuất? Cảm ơn!

Trả lời

5

Thông báo lỗi đề xuất thêm 'static ràng buộc vào thông số loại T. Nếu bạn làm điều này, nó sẽ thoát khỏi những lỗi đầu tiên:

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

Các 'static ràng buộc là cần thiết để đảm bảo rằng giá trị trả về bởi task có thể sống lâu hơn chức năng nơi task chạy. Read more about the 'static lifetime.

Lỗi thứ hai là bạn đang đi qua một đóng cửa, trong khi run mong đợi một con trỏ hàm. Một cách để khắc phục điều này bằng cách thay đổi task từ một kết thúc với một fn:

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

Dưới đây là đoạn code làm việc hoàn chỉnh:

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

này là rất tốt, cảm ơn! Tôi đã cố gắng giải quyết phiên bản đóng cửa ở đây: http://is.gd/8UwpjT - Thêm ''tĩnh' luôn cảm thấy giống như một sự lựa chọn bẩn thỉu. Các tài liệu nói rằng nó có nghĩa là các mục sẽ kéo dài cho cuộc đời của chương trình. Đây có phải là hành động xấu không? Khi nào nó được chấp nhận để sử dụng thời gian sống tĩnh? – jocull

+0

Sau khi thử nghiệm một số, tôi * nghĩ * Tôi hiểu rồi ... http://is.gd/8KWutk ''static' có nghĩa là Trait đã cho là tĩnh - không phải là mục được chuyển vào! Điều này có ý nghĩa hơn. – jocull