rust 当我尝试将一个值关联到一个变量来匹配一个dyn参数时,为什么会出现类型不匹配的错误?

iezvtpos  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(123)

我正在尝试初始化一个结构体,它是:

struct Task {
    future: Mutex<Pin<Box<dyn Future<Output = ()> + Send>>>,
    executor: channel::Sender<Arc<Task>>,
}

字符串
它工作得很好,当我这样做:

fn spawn<F>(future: F, sender: &channel::Sender<Arc<Task>>)
    where
        F: Future<Output = ()> + Send + 'static,
    {
        let task = Arc::new(Task {
            future: Mutex::new(Box::pin(future)),
            executor: sender.clone(),
        });
        sender.send(task).unwrap();
    }


然而,当我尝试先将future关联到一个变量时,会发生类型不匹配的错误:

fn spawn<F>(future: F, sender: &channel::Sender<Arc<Task>>)
    where
        F: Future<Output = ()> + Send + 'static,
    {
        let future = Mutex::new(Box::pin(future));
        let task = Arc::new(Task {
            future,
            executor: sender.clone(),
        });
        sender.send(task).unwrap();
    }


错误代码:

error[E0308]: mismatched types
  --> src\bin\test.rs:76:13
   |
70 |     fn spawn<F>(future: F, sender: &channel::Sender<Arc<Task>>)
   |              - this type parameter
...
76 |             future,
   |             ^^^^^^ expected `Mutex<Pin<Box<...>>>`, found `Mutex<Pin<Box<F>>>`   
   |
   = note: expected struct `std::sync::Mutex<Pin<Box<(dyn futures::Future<Output = ()> + std::marker::Send + 'static)>>>`
              found struct `std::sync::Mutex<Pin<Box<F>>>`
   = help: type parameters must be constrained to match other types


在我显式指定future的类型后,错误被修复:

let future: Mutex<Pin<Box<dyn Future<Output = ()> + Send>>> = Mutex::new(Box::pin(future));


为什么会这样?是因为编译器不能自动推断dyn类型吗?

piok6c0g

piok6c0g1#

编译器不会尝试将Pin<Box<F>>强制转换为Pin<Box<dyn Future>>:当它看到这个表情时,它不相信它是需要的。它没有任何提示需要Pin<Box<dyn Future>>。只有在构建Mutex之后,您才看到您期望的是Mutex<Pin<Box<dyn Future>>>,并尝试将Mutex<Pin<Box<F>>>强制为Mutex<Pin<Box<dyn Future>>>
但是强制子不是传递的:Pin<Box<F>>可以强制转换为Pin<Box<dyn Future>>并不意味着Mutex<Pin<Box<F>>>可以强制转换为Mutex<Pin<Box<dyn Future>>>。因此编译器强制转换失败,并报告错误。
您只需要提示编译器在正确的位置强制类型。一种方法是像你做的那样;另一种是使用as

fn spawn<F>(future: F, sender: &channel::Sender<Arc<Task>>)
    where
        F: Future<Output = ()> + Send + 'static,
    {
        let future = Mutex::new(Box::pin(future) as Pin<Box<dyn Future<Output = ()> + Send>>);
        let task = Arc::new(Task {
            future,
            executor: sender.clone(),
        });
        sender.send(task).unwrap();
    }

字符串

相关问题