Как передать метод в функцию, для которой требуется параметр времени жизни stati c? - PullRequest
0 голосов
/ 01 марта 2020

Как передать метод в функцию, учитывая, что функция берет «обработчик» со временем жизни c?

(Точный вариант использования этого - создание Железо Цепочка в структуре).

Учитывая, что у нас есть следующая структура Chain:

struct Chain
{
    f: Box<dyn Fn()>
}

impl Chain
{
    fn new(handler: impl Fn() + 'static) -> Self
    {
        return Chain { f: Box::new(handler) };
    }

    fn invoke(&self)
    {
        (self.f)();
    }
}

При попытке создать экземпляр этого Chain используя замыкание, а также передавая метод в замыкании ...

struct MyStruct
{
    the_answer: u32
}

impl MyStruct
{
    pub fn run(&self)
    {
        let closure = || {
            println!("Closure called");
            self.printer_method(String::from("printer_method")); // <-- Problematic line
        };

        let chain = Chain::new(closure);

        chain.invoke();
    }

    fn printer_method(&self, msg: String)
    {
        // Access to self.the_answer
        println!("The answer is {}, your message is: {}", self.the_answer, msg);
    }
}

... компилятор выдает следующую ошибку:

error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements

I ' Мы поиграли с идеей объявления MyStruct и его членов stati c, но требование создания нескольких независимых экземпляров структуры является обязательным требованием (см. несколько экземпляров веб-сервера Iron).

Вот ссылка Playground .

1 Ответ

2 голосов
/ 02 марта 2020

В вашем закрытии:

let closure = || {
    println!("Closure called");
    self.printer_method(String::from("printer_method")); // <-- here
};

Вы захватываете &MyStruct из-за вызова метода. Так как замыкания в ржавчине в основном просто структуры с методом «call», это замыкание не может быть «stati c», потому что оно переживет ссылку на MyStruct. Решение состоит в том, чтобы получить generic c в течение этого срока:

struct Chain<'a>
{
    f: Box<dyn Fn() +'a>
}

impl<'a> Chain<'a>
{
    fn new(handler: impl Fn() + 'a) -> Self
    {
        return Chain { f: Box::new(handler) };
    }

    fn invoke(&self)
    {
        (self.f)();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...