【问题标题】:how to send a closure with captures through the mpsc channel in rust?如何通过 rust 中的 mpsc 通道发送带有捕获的闭包?
【发布时间】:2021-11-09 11:33:47
【问题描述】:

我想实现一个可以执行队列中打包任务的执行器。首先,我 希望使用闭包将不同类型的函数变成一种类型,并将闭包发送到一个通道中,然后在另一个线程中接收并执行它。代码如下:

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 的错误信息是我所见过的最清晰、信息最丰富、最有帮助的一些。将它们包含在您的问题中。
  • 主要原因是我不知道如何使用带有捕获的闭包类型,因为它具有不同的捕获类型!如果没有捕获的闭包,我可以使用 fn() 来解决这个问题。

标签: rust closures channel


【解决方案1】:

每个闭包都有自己的类型,Rust(目前)没有任何语法来注释这些类型。即使是这样,为这样的闭包创建一个通道也有点没有意义,因为只有一个闭包可以通过通道发送。

请发送trait objects:

let b = Box::new(packed_method_task!(area1, rect1, 60, 90));
let (tx, rx) = mpsc::channel::<Box<dyn Send + Fn()>>();

Playground.

【讨论】:

    猜你喜欢
    • 2020-02-25
    • 1970-01-01
    • 1970-01-01
    • 2020-12-26
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多