【问题标题】:Identity closure on references引用上的身份闭包
【发布时间】:2019-10-13 18:21:53
【问题描述】:

我有一个需要闭包的函数。闭包接受一个引用并返回任何类型K

fn take_closure<T, K>(f: impl FnMut(&T)->K) {/*...*/}

如果我使用身份函数调用take_closure,即

struct S;
fn test() {
    take_closure(|s: &S| s)
}

编译器抱怨:

error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements

我认为问题在于 K 是一种单一类型,但闭包必须在所有生命周期内都有效,因此闭包的结果必须类似于 K + '(lifetime of closure parameter)

指定K 的寿命与&amp;T 一样长并没有真正的帮助:

fn take_closure<'a, T: 'a + Default, K: 'a>(mut f: impl FnMut(&'a T)->K) {
    let t = Default::default();
    f(&t); // error[E0597]: `t` does not live long enough
}

因此,我尝试了更高等级的特征界限:

fn take_closure<F, T: Default, K>(mut f: F)
    where for<'a> F: FnMut(&'a T)->K // <- (how) can I specify that K: 'a 
{
    let t = Default::default();
    f(&t);
}

#[derive(Default)]
struct S;
fn test() {
    take_closure(|s: &S| s) // error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
}

有没有办法相应地指定take_closure? IE。我可以以某种方式指定for&lt;'a&gt;,我的FnMut(&amp;'a T) 产生一个K 令人满意的生命周期'a

【问题讨论】:

  • 您打算如何通过返回s(借用)将&amp;S(借用)转换为K(拥有),究竟是什么?那里发生了一些非常可疑的事情。
  • @SébastienRenauld 我认为K 不一定是所有的。特别是,我们应该有K==&amp;S(至少我是这么认为的)。

标签: reference rust closures lifetime


【解决方案1】:

您可以在声明函数时指定K 不能超过&amp;T

fn take_closure<'a, T: 'a, K: 'a>(f: impl FnMut(&'a T)->K) {}

struct S;
fn test() {
    take_closure(|s: &S| s)
}

【讨论】:

  • 我把问题简化得太多了,抱歉。实际上,我试过这个,但如果我真的想在take_closure 中使用f,这不会奏效。我想我 - 至少 - 必须为FnMut 指定任意生命周期(请参阅我编辑的问题)。无论如何感谢您的回答。
猜你喜欢
  • 2012-02-29
  • 2012-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-13
  • 1970-01-01
  • 2020-09-27
  • 1970-01-01
相关资源
最近更新 更多