英文:
Trouble understanding `self` escapes the method body here
问题
I'm very new to Rust. I've been through the various books etc but I'm consistently having issues with code like the following.
This is a simple repro that follows the function prototype of a package I'm using
#[derive(Default)]
struct DoSomething {
x: i32,
}
fn some_func(loader: impl FnOnce() + 'static) {}
impl DoSomething {
async fn do_something(&mut self) {
some_func(|| {
self.x = 100;
});
}
}
I get a compiler error in the call to some_func
error[E0521]: borrowed data escapes outside of method
--> src\main.rs:44:9
|
43 | async fn do_something(&mut self) {
| ---------
| |
| `self` is a reference that is only valid in the method body
| let's call the lifetime of this reference `'1`
44 | / some_func(|| {
45 | | self.x = 100;
46 | | });
| | ^
| | |
| |__________`self` escapes the method body here
| argument requires that `'1` must outlive `'static`
Now I get that because the closure captures the reference of self and combined with 'static on some_func, the borrow checker can't be sure that self will be valid when the closure is eventually executed. Is that correct?
Now the million dollar question. What's the right way to do something like this?
For completeness, the package I'm using is called callback-future which allows me to turn a callback into a future. The full code I want to get working is:
async fn some_async(&mut self) -> Result<String, i32> {
CallbackFuture::new(|complete| {
self.cb = Some(complete);
})
.await
}
The idea is to store the complete Fn passed into the closure so I can execute when some later async workflows have completed.
英文:
I'm very new to Rust. I've been through the various books etc but I'm consistently having issues with code like the following.
This is a simple repro that follows the function prototype of a package I'm using
#[derive(Default)]
struct DoSomething {
x: i32,
}
fn some_func(loader: impl FnOnce() + 'static) {}
impl DoSomething {
async fn do_something(&mut self) {
some_func(|| {
self.x = 100;
});
}
}
I get a compiler error in the call to some_func
error[E0521]: borrowed data escapes outside of method
--> src\main.rs:44:9
|
43 | async fn do_something(&mut self) {
| ---------
| |
| `self` is a reference that is only valid in the method body
| let's call the lifetime of this reference `'1`
44 | / some_func(|| {
45 | | self.x = 100;
46 | | });
| | ^
| | |
| |__________`self` escapes the method body here
| argument requires that `'1` must outlive `'static`
Now I get that because the closure captures the reference of self and combined with 'static on some_func, the borrow checker can't be sure that self will be valid when the closure is eventually executed. Is that correct?
Now the million dollar question. Whats the right way to do something like this?
For completeness, the package I'm using is called callback-future which allows me to turn a callback into a future. The full code I want to get working is:
async fn some_async(&mut self) -> Result<String, i32> {
CallbackFuture::new(|complete| {
self.cb = Some(complete);
})
.await
}
The idea is to store the complete Fn passed into the closure so I can execute when some later async workflows have completed.
答案1
得分: 0
因为库要求一个由'static
绑定的FnOnce
,所以您必须确保传递到闭包中的所有引用也至少是'static
。这是最简单的解决方案:
impl DoSomething {
async fn do_something(&'static mut self) {
some_func(|| self.x = 100);
}
}
我建议您查看不同的crate,通常您必须泄漏内存以获得静态引用。
英文:
Because the library requires a FnOnce
bound by 'static
, you must ensure that all references passed into the closure are also at least 'static
. This is the easiest solution:
impl DoSomething {
async do_something(&'static mut self) {
some_func(|| self.x = 100);
}
}
I recommend looking into a different crate, usually you have to leak memory to obtain a static reference.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论