How do I store a variable of type `impl Trait` in a struct?的解决方案建议创建一个Future特征对象。在我的实际代码中执行此操作会产生一个错误,即类型不是Send,但有效版本和无效版本之间的唯一区别是是否存在强制转换为dyn Future的类型。

为什么编译器将它们视为不同的,我该如何解决该问题?

这是问题的简化版本:

use std::future::Future;

fn uses_impl_trait() -> impl Future<Output = i32> {
    async { 42 }
}

fn uses_trait_object() -> Box<dyn Future<Output = i32>> {
    Box::new(async { 42 })
}

fn requires_send<T: Send>(_: T) {}

fn example() {
    requires_send(uses_impl_trait()); // Works
    requires_send(uses_trait_object()); // Fails
}

error[E0277]: `dyn std::future::Future<Output = i32>` cannot be sent between threads safely
  --> src/lib.rs:15:19
   |
11 | fn requires_send<T: Send>(_: T) {}
   |    -------------    ---- required by this bound in `requires_send`
...
15 |     requires_send(uses_trait_object());
   |                   ^^^^^^^^^^^^^^^^^^^ `dyn std::future::Future<Output = i32>` cannot be sent between threads safely
   |
   = help: the trait `std::marker::Send` is not implemented for `dyn std::future::Future<Output = i32>`
   = note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<dyn std::future::Future<Output = i32>>`
   = note: required because it appears within the type `std::boxed::Box<dyn std::future::Future<Output = i32>>`

Sending trait objects between threads in Rust,我已经知道可以将trait对象更改为Box<dyn Future<Output = i32> + Send>,但是为什么存在这种区别?

最佳答案

出于人体工程学的原因。 RFC 1522, conservative impl trait专​​门讨论此设计决策:



也可以看看:

  • What is an auto trait in Rust?
  • 关于rust - 为什么 `impl Trait`返回值实现了Send而 `Box<dyn Trait>`没有实现?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59037266/

    10-12 20:20