[英]“error: closure may outlive the current function” but it will not outlive it
當我嘗試編譯以下代碼時:
fn main() {
(...)
let mut should_end = false;
let mut input = Input::new(ctx);
input.add_handler(Box::new(|evt| {
match evt {
&Event::Quit{..} => {
should_end = true;
}
_ => {}
}
}));
while !should_end {
input.handle();
}
}
pub struct Input {
handlers: Vec<Box<FnMut(i32)>>,
}
impl Input {
pub fn new() -> Self {
Input {handlers: Vec::new()}
}
pub fn handle(&mut self) {
for a in vec![21,0,3,12,1] {
for handler in &mut self.handlers {
handler(a);
}
}
}
pub fn add_handler(&mut self, handler: Box<FnMut(i32)>) {
self.handlers.push(handler);
}
}
我收到此錯誤:
error: closure may outlive the current function, but it borrows `should_end`, which is owned by the current function
我不能簡單地將move
添加到閉包中,因為我需要稍后在主循環中使用should_end
。 我的意思是,我可以,但由於bool
是Copy
,它只會影響閉包內的should_end
,因此程序會永遠循環。
據我所知,由於input
是在main函數中創建的,並且閉包存儲在input
,因此它不可能比當前函數更長。 有沒有辦法向Rust表達封閉不會比main
更長? 或者是否有可能我看不到關閉將比main
更長? 在后一種情況下,它有一種方法可以強迫它只與main
生活一樣長嗎?
我是否需要重構我處理輸入的方式,或者是否有某些方法可以使其工作。 如果我需要重構,我在哪里可以看到Rust的一個很好的例子?
這是一個簡化版的圍欄 。 我可能在其中犯了一個可能導致瀏覽器崩潰的錯誤。 我碰巧遇到過一次,所以,要小心。
問題不是你的閉包,而是add_handler
方法。 完全展開它看起來像這樣:
fn add_handler<'a>(&'a mut self, handler: Box<FnMut(i32) + 'static>)
正如您所看到的,特征對象上存在一個隱式的'static
綁定”。 顯然我們不希望這樣,所以我們引入第二個生命周期'b
:
fn add_handler<'a, 'b: 'a>(&'a mut self, handler: Box<FnMut(i32) + 'b>)
由於您要將handler
對象添加到Input::handlers
字段,因此該字段不能超過handler
對象的范圍。 因此,我們還需要限制其壽命:
pub struct Input<'a> {
handlers: Vec<Box<FnMut(i32) + 'a>>,
}
這再次要求impl具有生命周期,我們可以在add_handler
方法中使用它。
impl<'a> Input<'a> {
...
pub fn add_handler(&mut self, handler: Box<FnMut(i32) + 'a>) {
self.handlers.push(handler);
}
}
現在剩下的就是使用Cell
來控制對should_end
標志的訪問。
以下是固定代碼的示例 :
use std::cell::Cell;
fn main() {
let should_end = Cell::new(false);
let mut input = Input::new();
input.add_handler(Box::new(|a| {
match a {
1 => {
should_end.set(true);
}
_ => {
println!("{} {}", a, should_end.get())
}
}
}));
let mut fail_safe = 0;
while !should_end.get() {
if fail_safe > 20 {break;}
input.handle();
fail_safe += 1;
}
}
pub struct Input<'a> {
handlers: Vec<Box<FnMut(i32) + 'a>>,
}
impl<'a> Input<'a> {
pub fn new() -> Self {
Input {handlers: Vec::new()}
}
pub fn handle(&mut self) {
for a in vec![21,0,3,12,1,2] {// it will print the 2, but it won't loop again
for handler in &mut self.handlers {
handler(a);
}
}
}
pub fn add_handler(&mut self, handler: Box<FnMut(i32) + 'a>) {
self.handlers.push(handler);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.