Как использовать границы признаков более высокого ранга с анонимным закрытием в возвращаемом типе

#generics #rust #higher-rank-types

Вопрос:

Возможно ли вернуть FnMut закрытие, которое принимает ссылку и возвращает ссылку с тем же временем жизни, что и требуется?

 fn fun(buf: amp;mut [f32], mut idx: usize) -> impl FnMut(amp;[i16]) -> amp;[i16] {
    |input| {
        buf[idx] = input[0] as f32;
        idx  = 1;
        amp;input[1..]
    }
}
 

Я пробовал такие вещи, как impl for<'a> FnMut(amp;'a [i16]) -> amp;'a [i16]) , и это дает

 error[E0482]: lifetime of return value does not outlive the function call
 --> src/main.rs:1:44
  |
1 | fn fun(buf: amp;mut [f32], mut idx: usize) -> impl for<'a> FnMut(amp;'a [i16]) -> amp;'a [i16] {
  |                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
note: the return value is only valid for the anonymous lifetime defined on the function body at 1:13
 --> src/main.rs:1:13
  |
1 | fn fun(buf: amp;mut [f32], mut idx: usize) -> impl for<'a> FnMut(amp;'a [i16]) -> amp;'a [i16] {
  |             ^^^^^^^^^^
 

Ответ №1:

  • Возвращаемая функция должна фиксироваться buf по значению (т. е. Использовать move )
  • Возвращаемая функция не должна переживать buf (срок 'buf службы указан в приведенном ниже фрагменте).:

Так:

 fn fun<'buf>(buf: amp;'buf mut [f32], mut idx: usize) -> impl FnMut(amp;[i16]) -> amp;[i16]   'buf {
    move |input| {
        buf[idx] = input[0] as f32;
        idx  = 1;
        amp;input[1..]
    }
}
 

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

1. Можете ли вы указать на документ или уточнить сами, что 'buf означает в этом контексте? Почему это не просто amp;'b [i16] так ?

2. @user1685095 'buf означает, что возвращаемая функция не должна пережить срок 'buf службы .