2016-11-11 7 views
2

У меня есть структура, которая содержит значение, и я хочу, чтобы получить функцию, которая работает на этом значении:Как вернуть замыкание со ссылкой на структуру?

struct Returner { 
    val: i32, 
} 

impl<'a> Returner { 
    fn get(&'a self) -> Box<Fn(i32) -> i32> { 
     return Box::new(|x| x + self.val); 
    } 
} 

Это терпит неудачу сборника: «типа [закрытие ...] не соответствует требуемой жизни» , Это связано с тем, что закрытие занимает self, что прекрасно для меня, потому что я не намерен использовать полученную функцию после разрушения структуры. Из того, что я собрал до сих пор, есть два способа сделать это возможным:

  1. Используйте move ключевое слово. Я не хочу использовать его, потому что он будет владеть объектом, и я хочу использовать его после того, как он вернул эту функцию.

  2. Явно указать время жизни замыкания, чтобы сообщить компилятору, что он имеет такое же время жизни, что и вызванная им структура.

Я думаю, что 2 является правильным способом в моей ситуации, но я не смог выяснить, как указать срок службы закрытия. Есть ли прямой способ сделать это, или я ошибаюсь, и это противоречит логике жизни Rust?

ответ

5

В общем, вы можете указать время жизни объекта коробочного признака, написав Box<Trait + 'a> и аналогично для признака объектов позади других видов указателей (если он опущен, то по умолчанию 'static по крайней мере, в случае Box). Поэтому в этом конкретном случае вам нужен тип возврата Box<(Fn(i32) -> i32) + 'a>.

Однако, когда вы это сделаете, вы увидите еще одну ошибку около self, не проживая достаточно долго. Причина в том, что (без move) замыкание зафиксирует ссылку на локальную переменную self. Решение состоит в использовании move. Это не перемещает объект Returner, он перемещает self, который является ссылкой на объект Returner.

Итак, в заключение:

struct Returner { 
    val: i32, 
} 

impl<'a> Returner { 
    fn get(&'a self) -> Box<(Fn(i32) -> i32) + 'a> { 
     return Box::new(move |x| x + self.val); 
    } 
} 
+1

Это я или это '' <'a> должны украшать 'get' и не' impl'? –

+1

@ MatthieuM. Вы правы, это должно быть. Это не имеет никакого значения здесь, потому что '' a' не встречается нигде, но это действительно неправильное место для квантификатора. – delnan

+0

@ Matthieu M. Я проверил оба пути, результаты те же. – Month

Смежные вопросы