2016-08-29 8 views
0

Я пытаюсь отправить сигнал из замыкания, используя следующий код.Отправка сигнала канала от замыкания

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

fn main() { 
    let (tx, rx) = channel(); 

    let t1 = thread::spawn(move || { 
     watch(|x| tx.send(x)); 
    }); 

    let t2 = thread::spawn(move || { 
     println!("{:?}", rx.recv().unwrap()); 
    }); 

    let _ = t1.join(); 
    let _ = t2.join(); 
} 

fn watch<F>(callback: F) where F : Fn(String) { 
    callback("hello world".to_string()); 
} 

Однако она не компиляции средств следующее сообщение об ошибке:

src/test.rs:8:19: 8:29 note: expected type `()` 
src/test.rs:8:19: 8:29 note: found type `std::result::Result<(), std::sync::mpsc::SendError<std::string::String>>` 

я упускаю что-то?

ответ

3

Вы заявили, что ваша функция watch получает замыкание типа Fn(String). Обычно тип замыкания включает его тип возврата: Fn(String) -> SomeReturnType. Fn(String) эквивалентен Fn(String) ->() и означает, что ваше закрытие должно возвращать пустой кортеж (). () часто используют похожие на void в С.

Однако закрытие вы пытаетесь использовать (|x| tx.send(x)) возвращает std::result::Result<(), std::sync::mpsc::SendError<std::string::String>> вместо. Вы можете использовать unwrap() на Result, чтобы проверить, что операция уже преуспела и сделать закрывающее возвращение ():

watch(|x| tx.send(x).unwrap()); 

В качестве альтернативы, вы можете объявить watch функции таким образом, чтобы он мог получить замыкание возвращения любого типа:

fn watch<F, R>(callback: F) 
    where F: Fn(String) -> R 
{ 
    // ... 
} 

Но Result должен быть проверен в любом случае.