我正在尝试创建Futures
的Vec
,以便与try_join_all
一起使用。
use futures::future::try_join_all;
struct Image {
pub file_name: String,
}
struct Storage;
impl Storage {
async fn upload(&self, filename: &str) -> Result<String, ()> {
Ok(filename.to_owned())
}
}
struct ImagesRepository {
storage: Storage,
}
impl ImagesRepository {
async fn upload_images(&self, images: &[Image]) -> Result<Vec<String>, ()> {
let futures = images
.iter()
.map(|image| {
let path_name = format!("somedirectory/{}", &image.file_name);
let future = self.storage.upload(path_name.as_str());
future
})
.collect::<Vec<_>>();
let results = try_join_all(futures).await?;
Ok(results)
}
}
但是,我遇到了以下编译器错误:
Compiling playground v0.0.1 (/playground)
error[E0515]: cannot return value referencing local variable `path_name`
--> src/lib.rs:30:17
|
26 | let future = self.storage.upload(path_name.as_str());
| ------------------ `path_name` is borrowed here
...
30 | future
| ^^^^^^ returns a value referencing data owned by the current function
For more information about this error, try `rustc --explain E0515`.
error: could not compile `playground` due to previous error
这是因为我向storage.upload
传递了一个对path_name
的引用,而path_name
只存在于闭包中。
我知道我可以将storage.upload
更改为使用String
,但这意味着要破坏使用此函数的其他部分的代码。
有没有办法修正这个编译器错误?
Minimal example - Rust Playground
1条答案
按热度按时间ego6inou1#
这其实很简单,你只需要把future Package 到另一个拥有这个字符串的future中,你可以用
async
块来实现,这个块用来创建一个特殊的匿名的Future
实现值(就像|...|
可以用来创建一个特殊的匿名的Fn*
实现值一样):(Playground)
创建一个future并从它返回等待另一个future的结果通常是一个反模式,但这是一个不反模式的情况,这是因为 Package future不仅代理内部future的ready值,它还负责在内部future准备就绪后运行
path_name
的析构函数。如果愿意,您甚至可以完全删除
path_name
变量: