vector - 试图修改 Rc 内的期货 Vec>
问题描述
我尝试等待并从期货中删除一个接一个Vec
的未来。这没用。我明白为什么它不起作用: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
解决方案
问题不在于引脚 - 盒装的未来可以安全地与它的引脚一起移动,因为盒子意味着未来是堆分配的,所以移动盒子不会移动未来。该图钉用于禁止将未来移出其框框,但您不要尝试这样做。您的代码无法编译,因为Vec::iter()
迭代了对元素的引用,并且您不能将对象移出引用,因为它会使原始值处于未定义状态。这种移动只允许用于可以简单复制的类型,例如数字或布尔值,这些类型由Copy
trait 标记。编译器的消息令人困惑,因为它提到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;
}
推荐阅读
- java - 如何在 Java 中将作为日期的字符串格式化为新的日期格式?
- javascript - 即使在使用其他模块定义变量之后,变量也未定义
- ios - #selector 函数在 Swift 4.2 中不起作用
- jquery - 局部视图中的访问元素
- git - GitHub 提交未链接到我的帐户
- css - 对表 td 使用两种 CSS 样式
- python - Zappa 部署错误:GET 请求产生 502 响应代码
- laravel - VueJs 2 点击似乎不起作用
- angular - 如何在角度测试中模拟 vis js 网络
- database - Eloquent - groupBy 和 sum() 的 hasManyThrough 关系