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专门讨论此设计决策:
也可以看看:
关于rust - 为什么 `impl Trait`返回值实现了Send而 `Box<dyn Trait>`没有实现?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59037266/