I would like to implement an executor that can execute the packaged task in its queue. Firstly,I hope to make different types of functions into one type using a cloure, then send the closure to channel, receive it in thread and execute it. The codes are below :
This is not the way it works, sadly, since different closures (even with exact same code) have different types. See this modification of your code (playground):
fn main() {
let rect1 = Rectangle { width: 30, height: 50 };
let b = packed_method_task!(area1, rect1, 60, 90);
let c = packed_method_task!(area1, rect1, 60, 90);
let (tx, rx) = mpsc::channel();
tx.send(b).unwrap();
tx.send(c).unwrap();
let handle= thread::spawn(move || {
let _received = rx.recv().unwrap();
_received();
});
handle.join();
}
It errors due to b and c having different types. Note that if you send only b or only c, it works - in your original code the error essentially tells you the following: "you're receiving something, I don't know yet what it is, so you can't call it"; by moving send(b) above thread::spawn, you allow type inference to kick in and to infer the exact type.
You can do this, but you'll need to send a Box<dyn Fn()>. The compiler will insert the necessary information for you to still be able to call it after you've received it. This adds a little bit of overhead, but is what you need to do if you want to send arbitrary closures. playground
fn main() {
println!("{}", invoke_1(1,2,3));
let rect1 = Rectangle { width: 30, height: 50 };
let b = packed_method_task!(area1, rect1, 60, 90);
let c = packed_method_task!(area1, rect1, 60, 90);
// specify the type here
let (tx, rx) = mpsc::channel::<Box<dyn Fn() + Send>>();
// Box values before sending them
tx.send(Box::new(b)).unwrap();
tx.send(Box::new(c)).unwrap();
let handle= thread::spawn(move || {
let _received = rx.recv().unwrap();
_received();
});
handle.join();
}