想在闭包参数里传可变借用,需要如何解决生命周期问题?
rustc 1.65.0
296 | do_demo(|demo| async move {
| ______________-----_^
| | | |
| | | return type of closure `impl Future<Output = String>` contains a lifetime `'2`
| | has type `&'1 mut Demo`
297 | | println!("demo: {:?}", demo);
298 | | demo.print_mut();
299 | | format!("test demo, id: {}", demo.id)
300 | | })
| |_____^ returning this value requires that `'1` must outlive `'2`
use std::future::Future;
#[derive(Debug)]
struct Demo {
id: i32,
name: String,
}
impl Demo {
fn print(self) {
println!("id:{}, name:{:?}", self.id, self.name);
}
fn print_mut(&mut self) {
println!("id:{}, name:{:?}", self.id, self.name);
}
}
async fn do_demo<F, U>(mut f: F) -> Result<(), String>
where
F: for<'a> FnMut(&'a Demo) -> U,
U: Future<Output = String>,
{
let demo = Demo {
id: 1,
name: "test".to_string(),
};
let ret = f(&demo).await;
demo.print();
println!("f() ret: {:?}", ret);
Ok(())
}
#[tokio::test]
async fn demo() {
do_demo(|demo| async move {
println!("demo: {:?}", demo);
demo.print_mut();
format!("test demo, id: {}", demo.id)
})
.await
.unwrap();
}
1
共 9 条评论, 1 页
评论区
写评论这样子是否符合你的需求呢?
--
👇
bianweiall: 感谢几位朋友的帮助,只使用GAT, 当我传入的闭包也需要返回Future时,在下面的示例中要如何去实现?
--
👇
wangbyby: 我理解,可能你需要GAT?
感谢几位朋友的帮助,只使用GAT, 当我传入的闭包也需要返回Future时,在下面的示例中要如何去实现?
--
👇
wangbyby: 我理解,可能你需要GAT?
个人觉得
#![feature(type_alias_impl_trait)]
更加优雅一些--
👇
Paradox: 想起来
GAT
已经 stable 了,那GAT
应该也能做?--
👇
Paradox: 这里报错的大概意思是无法推断返回的闭包的生命周期与参数生命周期的关系,所以只要在函数签名上标注就好了。
但就我所知,
stable rust
似乎目前还做不到这一点,需要用到其他 feature 来做到这一点,这里我用了#![feature(type_alias_impl_trait)]
playground
不过如上面说的,
async runtime
要求生命周期为'static
,所以看起来并没有什么用(我理解,可能你需要GAT?
HRTB问题,一些简单代码看似可以但并不能在async中使用捕获变量。如果可以接受捕获函数的限制是不需要nightly的,例如: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=11d3892fc874d229f8ec30e0b940cf44
想起来
GAT
已经 stable 了,那GAT
应该也能做?--
👇
Paradox: 这里报错的大概意思是无法推断返回的闭包的生命周期与参数生命周期的关系,所以只要在函数签名上标注就好了。
但就我所知,
stable rust
似乎目前还做不到这一点,需要用到其他 feature 来做到这一点,这里我用了#![feature(type_alias_impl_trait)]
playground
不过如上面说的,
async runtime
要求生命周期为'static
,所以看起来并没有什么用(这里报错的大概意思是无法推断返回的闭包的生命周期与参数生命周期的关系,所以只要在函数签名上标注就好了。
但就我所知,
stable rust
似乎目前还做不到这一点,需要用到其他 feature 来做到这一点,这里我用了#![feature(type_alias_impl_trait)]
playground
不过如上面说的,
async runtime
要求生命周期为'static
,所以看起来并没有什么用(When you spawn a task on the async runtime, its type's lifetime must be 'static. This means that the spawned task must not contain any references to data owned outside the task.
It is a common misconception that 'static always means "lives forever", but this is not the case. Just because a value is 'static does not mean that you have a memory leak. You can read more in Common Rust Lifetime Misconceptions.
https://github.com/pretzelhammer/rust-blog/blob/master/posts/common-rust-lifetime-misconceptions.md#2-if-t-static-then-t-must-be-valid-for-the-entire-program
async 不是强制要求'static 吗? 能传借用?