Срок службы закрытия в ржавчине благодаря простому рисунку

#struct #rust #closures #lifetime

Вопрос:

Я пытаюсь воссоздать простой шаблон обратного вызова в Rust, используя 2 структуры. Один из них передаст немного логики для выполнения, когда другой будет готов. Проблема здесь в том, что логика будет выполняться только в том случае, если определенное значение из структуры является истинным.

Я могу понять, почему 'static в этом случае ссылка на Foo должна существовать, но я не уверен, как ее реорганизовать, чтобы она компилировалась.

Похоже на довольно обычный вариант использования, но, возможно, я что-то упускаю, так как я новичок в Ржавчине.

 struct Foo {
    value: bool,
}

struct Bar {
    closure: Box<dyn Fn() -> ()>,
}

impl Foo {
    fn new() -> Self {
        Foo {
            value: false,
        }
    }
    fn set_closure(amp;self, b: amp;mut Bar) {
        b.closure = self.get_closure();
    }
    fn get_closure(amp;self) -> Box<dyn Fn() -> ()> {
        return Box::new(|| {
            if self.value {
                println!("true");
            } else {
                println!("false");
            }
        });
    }
}
impl Bar {
    fn new() -> Self {
        Bar {
            closure: Box::new(|| {})
        }
    }
    
}
fn main() {
    let foo = Foo::new();
    let mut bar = Bar::new();
    foo.set_closure(amp;mut bar);
    let closure = bar.closure;
    closure();
}
 

Ссылка на игровую площадку -> >здесь

Ответ №1:

Вам нужно внести move значение в закрытие:

 fn get_closure(amp;self) -> Box<dyn Fn() -> ()> {
    let value = self.value;
    Box::new(move || {
        if value {
            println!("true");
        } else {
            println!("false");
        }
    })
}
 

Обратите внимание, что в вашем примере значение- bool это Копия. Если нет, вы можете либо захватить ссылку, либо клонировать ее. (При захвате ссылки вам, возможно, потребуется скорректировать там некоторые периоды жизни).
Игровая площадка

Комментарии:

1. @Stargateur спасибо за коррекцию стиля