我尝试等待并从 future 的Vec
中删除一对一的 future 。这没用。我了解为什么它不起作用:Pin
无法复制。但是如何纠正这个错误呢?
extern crate futures;
use std::cell::{RefCell};
use std::rc::Rc;
use std::pin::Pin;
use std::future::Future;
use futures::channel::oneshot::Canceled;
use futures::executor::block_on;
use futures::future::select_all;
fn run_queries_body() {
let _futures: Vec<Pin<Box<dyn Future<Output=Result<(), Canceled>>>>> = Vec::new();
let futuresRc = Rc::new(RefCell::new(_futures)); // TODO: Cell instead
// This in actual could be called inside another future, so we need Rc<RefCell<...>>
let mut futures = futuresRc.borrow_mut();
let f3 = futures.iter().map(|x| *x);
let (_res, _idx, remaining_futures) = block_on(select_all(f3));
*futures = remaining_futures;
}
error[E0507]: cannot move out of `*x` which is behind a shared reference
--> src/lib.rs:16:37
|
16 | let f3 = futures.iter().map(|x| *x);
| ^^ move occurs because `*x` has type `std::pin::Pin<std::boxed::Box<dyn futures::Future<Output = std::result::Result<(), futures::channel::oneshot::Canceled>>>>`, which does not implement the `Copy` trait
最佳答案
问题不在钉子上-装箱的 future 可以安全地与钉子一起移动,因为箱子意味着将来是堆分配的,因此移动箱子不会移动 future 。该固定销用于禁止将 future 从其包装箱中移出,但您不要尝试这样做。您的代码无法编译,因为Vec::iter()
会在对元素的引用上进行迭代,并且您无法将对象移出引用,因为它将使原始值保持未定义状态。这种移动仅适用于可以被简单复制的类型,例如数字或 bool 值,这些类型由Copy
特性标记。编译器的消息令人困惑,因为它提到了Pin<...>
,但之所以如此,是因为这是引用后面的文字类型,并且编译器报告所涉及的类型不是Copy
,而没有暗示有关Pin
语义的任何内容。
一个简单的解决方法是使futures
成为选项的向量。这允许您通过在Option::take
上调用 &mut Option<T>
来拥有向量的可变迭代器,从而从向量中提取元素。这是定义明确的,因为它可以提取值,但也可以将None
留在向量的旧位置。
在您的情况下,您将使用 iter_mut()
(playground)遍历向量:
pub fn run_queries_body() {
let futures: Vec<Option<Pin<Box<dyn Future<Output = Result<(), Canceled>>>>>> = vec![];
let futures_rc = Rc::new(RefCell::new(futures));
let mut futures = futures_rc.borrow_mut();
let f3 = futures.iter_mut().map(|f| f.take().unwrap());
let (_res, _idx, remaining_futures) = block_on(select_all(f3));
*futures = remaining_futures.into_iter().map(Some).collect();
}
正如@Jmb所指出的,一种更简单的方法是使用 Vec::drain
,它从向量中删除元素,并为您提供对删除的元素(playground)的迭代器:pub fn run_queries_body() {
let futures: Vec<Pin<Box<dyn Future<Output = Result<(), Canceled>>>>> = vec![];
let futures_rc = Rc::new(RefCell::new(futures));
let mut futures = futures_rc.borrow_mut();
let f3 = futures.drain(..);
let (_res, _idx, remaining_futures) = block_on(select_all(f3));
*futures = remaining_futures;
}
关于vector - 试图在Rc <RefCell <... >>内部修改 future Vec,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63801495/