问题
I'm trying to send a signal from within a closure, using the following code.
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());
}
However, it fails compiling raising the following error:
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>>`
Am I missing something?
回答1:
You have declared that your watch
function receives a closure of type Fn(String)
. Usually a closure type includes its return type: Fn(String) -> SomeReturnType
. Fn(String)
is equivalent to Fn(String) -> ()
and means that your closure should return an empty tuple ()
. ()
is often used similar to void
in C.
However, the closure you're trying to use (|x| tx.send(x)
) returns std::result::Result<(), std::sync::mpsc::SendError<std::string::String>>
instead. You can use unwrap()
on the Result
to check that the operation have succeded and to make the closure return ()
:
watch(|x| tx.send(x).unwrap());
Alternatively, you can declare watch
function in such way so it can receive a closure returning any type:
fn watch<F, R>(callback: F)
where F: Fn(String) -> R
{
// ...
}
But the Result
should be checked anyway.
来源:https://stackoverflow.com/questions/39216185/sending-channel-signal-from-a-closure