您如何通过采用 &mut self 的方法对存储在结构中的 Future 调用 future::select?
How do you call future::select on a Future stored in a struct from a method that takes &mut self?
我想将我们偶尔等待的未来存储在结构中。我的用例是有一个信号告诉我的网络数据包处理程序正常关闭。一个最小的例子可能看起来像这样,依赖于期货 0.3:
use futures::{
executor::block_on,
future::{pending, select, Either, Future},
}; // 0.3.4
struct Foo<F: Future + Unpin> {
fut: F,
fut_opt: Option<F>,
}
impl<F: Future + Unpin> Foo<F> {
async fn wait(self: &mut Self) {
let bar = pending::<&str>();
match select(self.fut, bar).await {
Either::Left(_) => println!("foo"),
Either::Right(_) => println!("bar"),
}
}
async fn wait_optional(self: &mut Self) {
let bar = pending::<&str>();
if let Some(foo) = self.fut_opt.take() {
match select(foo, bar).await {
Either::Left(_) => println!("foo"),
Either::Right((_, foo_fut)) => {
self.fut_opt.replace(foo_fut);
println!("bar")
}
}
}
}
}
fn main() {
let mut foo = Foo {
fut: pending::<()>(),
fut_opt: Option::from(pending::<()>()),
};
block_on(foo.wait())
}
问题是 select
想要移动 fn wait(..)
版本中的值,所以我遇到编译错误:
error[E0507]: cannot move out of `self.fut` which is behind a mutable reference
--> src/main.rs:14:22
|
14 | match select(self.fut, bar).await {
| ^^^^^^^^ move occurs because `self.fut` has type `F`, which does not implement the `Copy` trait
可以在 fn wait_optional
中看到我想出的解决方法:我正在(ab)使用 Option
来存储未来,需要时将其取出然后放回原处作为 select
returns Either
未曾期待的未来。这编译并且似乎工作得很好 - 但感觉很糟糕。有没有 "proper" 方法来实现这个目标?
对未来进行可变引用:
use futures::{
executor::block_on,
future::{pending, select, Either, Future},
}; // 0.3.4
struct Foo<F: Future + Unpin> {
fut: F,
}
impl<F: Future + Unpin> Foo<F> {
async fn wait(&mut self) {
let bar = pending::<&str>();
match select(&mut self.fut, bar).await {
Either::Left(_) => println!("foo"),
Either::Right(_) => println!("bar"),
}
}
}
fn main() {
let mut foo = Foo {
fut: pending::<()>(),
};
block_on(foo.wait())
}
这是因为 Future
是 implemented for any mutable reference to a Future
但有某些限制:
impl<'_, F> Future for &'_ mut F
where
F: Unpin + Future + ?Sized,
另请参阅:
- Using the same iterator multiple times in Rust
- Temporarily move out of borrowed content
我想将我们偶尔等待的未来存储在结构中。我的用例是有一个信号告诉我的网络数据包处理程序正常关闭。一个最小的例子可能看起来像这样,依赖于期货 0.3:
use futures::{
executor::block_on,
future::{pending, select, Either, Future},
}; // 0.3.4
struct Foo<F: Future + Unpin> {
fut: F,
fut_opt: Option<F>,
}
impl<F: Future + Unpin> Foo<F> {
async fn wait(self: &mut Self) {
let bar = pending::<&str>();
match select(self.fut, bar).await {
Either::Left(_) => println!("foo"),
Either::Right(_) => println!("bar"),
}
}
async fn wait_optional(self: &mut Self) {
let bar = pending::<&str>();
if let Some(foo) = self.fut_opt.take() {
match select(foo, bar).await {
Either::Left(_) => println!("foo"),
Either::Right((_, foo_fut)) => {
self.fut_opt.replace(foo_fut);
println!("bar")
}
}
}
}
}
fn main() {
let mut foo = Foo {
fut: pending::<()>(),
fut_opt: Option::from(pending::<()>()),
};
block_on(foo.wait())
}
问题是 select
想要移动 fn wait(..)
版本中的值,所以我遇到编译错误:
error[E0507]: cannot move out of `self.fut` which is behind a mutable reference
--> src/main.rs:14:22
|
14 | match select(self.fut, bar).await {
| ^^^^^^^^ move occurs because `self.fut` has type `F`, which does not implement the `Copy` trait
可以在 fn wait_optional
中看到我想出的解决方法:我正在(ab)使用 Option
来存储未来,需要时将其取出然后放回原处作为 select
returns Either
未曾期待的未来。这编译并且似乎工作得很好 - 但感觉很糟糕。有没有 "proper" 方法来实现这个目标?
对未来进行可变引用:
use futures::{
executor::block_on,
future::{pending, select, Either, Future},
}; // 0.3.4
struct Foo<F: Future + Unpin> {
fut: F,
}
impl<F: Future + Unpin> Foo<F> {
async fn wait(&mut self) {
let bar = pending::<&str>();
match select(&mut self.fut, bar).await {
Either::Left(_) => println!("foo"),
Either::Right(_) => println!("bar"),
}
}
}
fn main() {
let mut foo = Foo {
fut: pending::<()>(),
};
block_on(foo.wait())
}
这是因为 Future
是 implemented for any mutable reference to a Future
但有某些限制:
impl<'_, F> Future for &'_ mut F
where
F: Unpin + Future + ?Sized,
另请参阅:
- Using the same iterator multiple times in Rust
- Temporarily move out of borrowed content