Почему время жизни этого закрытия меняется в зависимости от, казалось бы, не связанных типов?

#rust

Вопрос:

С помощью кода

 fn foolt;'a, 'bgt;(  state: amp;'b mut i32, ) -gt; impl FnMut(amp;'a str) -gt; amp;'static str   'b {  |s| "hi" }  

Я получаю сообщение об ошибке

 error[E0482]: lifetime of return value does not outlive the function call 112 | ) -gt; impl FnMut(amp;'a str) -gt; amp;'static str   'b {  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: the return value is only valid for the lifetime `'a` as defined on the function body at 110:9 110 | fn foo1lt;'a, 'bgt;(  | ^^  

Но каким-то образом код

 fn foo2lt;'a, 'bgt;(  state: amp;'b mut Optionlt;amp;'a i32gt;, ) -gt; impl FnMut(amp;'a str) -gt; amp;'static str   'b {  |s| "hi" }  

компилируется без ошибок. Почему тип state изменяет срок службы закрытия?

Ответ №1:

С типом amp;'b mut Optionlt;amp;'a i32gt; Rust определяет срок 'a: 'b службы ( 'a переживает 'b ). Эта граница необходима для того, чтобы сигнатура функции была правильно сформирована. Вы можете добавить эту привязку явно, чтобы избежать ошибки:

 fn foolt;'a, 'bgt;(  state: amp;'b mut i32, ) -gt; impl FnMut(amp;'a str) -gt; amp;'static str   'b where  'a: 'b, {  |s| "hi" }  

Однако, если параметр не используется 'a , вместо этого 'a должна быть привязка признака более высокого ранга:

 fn foolt;'bgt;(  state: amp;'b mut i32, ) -gt; impl forlt;'agt; FnMut(amp;'a str) -gt; amp;'static str   'b {  |s| "hi" }  

Fn Семейство признаков является особенным в том, что они позволяют полностью опустить время жизни (следуя тем же правилам fn выделения, что и подписи), так что это эквивалентно:

 fn foolt;'bgt;(  state: amp;'b mut i32, ) -gt; impl FnMut(amp;str) -gt; amp;'static str   'b {  |s| "hi" }  

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

1. Так что же тогда означает ошибка? Является ли тип закрытия недопустимым, поскольку для него требуется аргумент со временем жизни, которое могло истечь к моменту его вызова? Я думал, что Руст сможет сделать вывод 'a на месте foo вызова.

2. Подписи функций @Dan должны быть полностью описаны. Я имею в виду, что при взгляде на единственную подпись не должно быть никаких предположений. Я полагаю, вы просто сбиты с толку, почему удаление 'a из времени жизни ввода вызывает жалобы rustc. В примере 'a время жизни отображается только в типах вывода и не имеет связи со временем жизни ввода, поэтому оно становится неограниченным , что запрещает rustc.