Ожидаемый параметр связанного времени жизни, конкретное время жизни найдено при попытке передать параметр <FnOnce> - PullRequest
0 голосов
/ 08 мая 2020

В приведенном ниже коде я пытаюсь передать Option<FnOnce(&mut Thing)> функции высшего порядка invoke_me_maybe(). Передаваемая функция будет вызвана, если она присутствует, и не будет вызываться в противном случае.

Option<FnOnce(&mut Thing)> построены с использованием as_some() из дополнительных методов черт на логических значениях, скопировано boolinator crate .

struct Thing{}

fn invoke_me_maybe<F: FnOnce(&mut Thing)>(t: &mut Thing, opt_f: Option<F>) {
    if let Some(f) = opt_f {
        f(t);
    }
}

trait BoolOption {
    fn as_some<T>(self, some: T) -> Option<T>;
}

impl BoolOption for bool {
    fn as_some<T>(self, some: T) -> Option<T> {
        if self { Some(some) } else { None }
    }
}

pub fn main() {
    let mut thing = Thing{};
    invoke_me_maybe(&mut thing, true.as_some(|t| {}));
}

Функция invoke_me_maybe() не сохраняет opt_f за пределами конца функции, поэтому нам не нужно заключать функцию в Box или что-то подобное.

Произошла следующая ошибка:

error[E0631]: type mismatch in closure arguments
  --> src/main.rs:21:33
   |
3  | fn invoke_me_maybe<F: FnOnce(&mut Thing)>(t: &mut Thing, opt_f: Option<F>) {
   |    ---------------    ------------------ required by this bound in `invoke_me_maybe`
...
21 |     invoke_me_maybe(&mut thing, true.as_some(|t| {}));
   |                                 ^^^^^^^^^^^^^---^^^^
   |                                 |            |
   |                                 |            found signature of `fn(_) -> _`
   |                                 expected signature of `for<'r> fn(&'r mut Thing) -> _`

error[E0271]: type mismatch resolving `for<'r> <[closure@src/main.rs:21:46: 21:52] as std::ops::FnOnce<(&'r mut Thing,)>>::Output == ()`
  --> src/main.rs:21:5
   |
3  | fn invoke_me_maybe<F: FnOnce(&mut Thing)>(t: &mut Thing, opt_f: Option<F>) {
   |    ---------------    ------------------ required by this bound in `invoke_me_maybe`
...
21 |     invoke_me_maybe(&mut thing, true.as_some(|t| {}));
   |     ^^^^^^^^^^^^^^^ expected bound lifetime parameter, found concrete lifetime

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0271, E0631.
For more information about an error, try `rustc --explain E0271`.
error: could not compile `playground`.

To learn more, run the command again with --verbose.

Вероятно, мне не хватает каких-то явных параметров времени жизни или чего-то в этом роде, но я не могу это понять. Разве fn(_) -> _ не соответствует for<'r> fn(&'r mut Thing) -> _?

1 Ответ

1 голос
/ 08 мая 2020

Использование замыканий в качестве функций высшего порядка сложно. Я заметил, что обычно помогает явное указание типа аргументов. В вашем случае это делает трюк :

    invoke_me_maybe(&mut thing, true.as_some(|t: &mut Thing| {}));

Проблема, похоже, в том, что invoke_me_maybe принимает аргумент generi c с множеством возможностей, а |t| {} может ничего не значат, и компилятор не может сопоставить оба. В этом случае помогает добавление аннотации типа.

Лично я считаю это ошибкой компилятора, но раньше я ошибался ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...