如何通过 Rust 中的 mpsc 通道发送带有捕获的闭包?
how to send a closure with captures through the mpsc channel in rust?
我想实现一个可以在队列中执行打包任务的执行器。首先,我
希望用一个闭包把不同类型的函数做成一个类型,把闭包发送到一个channel中,然后在另一个线程中接收并执行。代码如下:
use std::thread;
use std::sync::mpsc;
macro_rules! packed_task {
($f:ident, $($arg:expr),*) => {move ||{
$f($($arg,)*)
}};
}
macro_rules! packed_method_task {
($f:ident,$ins:ident, $($arg:expr),*) => {move ||{
$ins.$f($($arg,)*);
}};
($f:ident,$ins:ident $($arg:expr),*) => {move ||{
$ins.$f($($arg,)*);
}};
}
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
fn area1(&self, w:u32, h:u32) -> u32 {
w*h
}
}
fn invoke_1(a:i32, b:i32, c:i32)->i32{
let fc = |x,y,z| x+y+z + 1;
return packed_task!(fc, a, b,c)();
}
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 (tx, rx) = mpsc::channel();
let handle= thread::spawn(move || {
let _received = rx.recv().unwrap();
_received();
});
tx.send(b).unwrap();
handle.join();
}
但是我编译有错误:
| let (tx, rx) = mpsc::channel();
| -------- consider giving this pattern the explicit type `(Sender<T>, std::sync::mpsc::Receiver<T>)`, with the type parameters
specified
我怎样才能做到这一点?
每个闭包都是它自己的类型,Rust(目前)没有任何语法来注释这些类型。即使是这样,为这样的闭包创建一个通道也有点毫无意义,因为只有一个闭包可以通过通道发送。
而是发送 trait objects:
let b = Box::new(packed_method_task!(area1, rect1, 60, 90));
let (tx, rx) = mpsc::channel::<Box<dyn Send + Fn()>>();
我想实现一个可以在队列中执行打包任务的执行器。首先,我 希望用一个闭包把不同类型的函数做成一个类型,把闭包发送到一个channel中,然后在另一个线程中接收并执行。代码如下:
use std::thread;
use std::sync::mpsc;
macro_rules! packed_task {
($f:ident, $($arg:expr),*) => {move ||{
$f($($arg,)*)
}};
}
macro_rules! packed_method_task {
($f:ident,$ins:ident, $($arg:expr),*) => {move ||{
$ins.$f($($arg,)*);
}};
($f:ident,$ins:ident $($arg:expr),*) => {move ||{
$ins.$f($($arg,)*);
}};
}
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
fn area1(&self, w:u32, h:u32) -> u32 {
w*h
}
}
fn invoke_1(a:i32, b:i32, c:i32)->i32{
let fc = |x,y,z| x+y+z + 1;
return packed_task!(fc, a, b,c)();
}
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 (tx, rx) = mpsc::channel();
let handle= thread::spawn(move || {
let _received = rx.recv().unwrap();
_received();
});
tx.send(b).unwrap();
handle.join();
}
但是我编译有错误:
| let (tx, rx) = mpsc::channel();
| -------- consider giving this pattern the explicit type `(Sender<T>, std::sync::mpsc::Receiver<T>)`, with the type parameters
specified
我怎样才能做到这一点?
每个闭包都是它自己的类型,Rust(目前)没有任何语法来注释这些类型。即使是这样,为这样的闭包创建一个通道也有点毫无意义,因为只有一个闭包可以通过通道发送。
而是发送 trait objects:
let b = Box::new(packed_method_task!(area1, rect1, 60, 90));
let (tx, rx) = mpsc::channel::<Box<dyn Send + Fn()>>();