预期的绑定寿命参数,在试图传递一个Option<FnOnce&gt时发现了具体的寿命。

问题描述 投票:0回答:1

在下面的代码中,我试图传递一个 "选项"。Option<FnOnce(&mut Thing)> 到高阶函数 invoke_me_maybe(). 如果被传递的函数存在,则会被调用,否则不会被调用。

Option<FnOnce(&mut Thing)> 用以下方法构建 as_some() 从booleans的附加特征方法中,复制了 愚公移山 箱子。

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) -> _?

rust lifetime higher-order-functions
1个回答
1
投票

使用闭包作为高阶函数是很棘手的。我注意到,明确写出参数的类型通常会有帮助。在你的例子中,它是 得心应手:

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

问题似乎是: invoke_me_maybe 取一个有很多可能性的通用论点,而 |t| {} 可能意味着任何东西,而编译器无法同时匹配这两种类型。在这种情况下,添加类型注释是有帮助的。

我个人认为这是一个编译器的bug,但我以前也错过...

© www.soinside.com 2019 - 2024. All rights reserved.