为什么此闭包的生命周期会根据看似不相关的类型而改变?



与代码

fn foo<'a, 'b>(
state: &'b mut i32,
) -> impl FnMut(&'a str) -> &'static str + 'b {
|s| "hi"
}

我得到一个错误

error[E0482]: lifetime of return value does not outlive the function call
112 | ) -> impl FnMut(&'a str) -> &'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 foo1<'a, 'b>(
|         ^^

但是代码

fn foo2<'a, 'b>(
state: &'b mut Option<&'a i32>,
) -> impl FnMut(&'a str) -> &'static str + 'b {
|s| "hi"
}

编译时没有错误。为什么state的类型会改变闭包的生存期?

对于&'b mut Option<&'a i32>类型,Rust推断出'a: 'b的生命周期边界('a'b更长寿)。这个边界是函数签名格式良好所必需的。您可以显式地添加此绑定以避免出现以下错误:

fn foo<'a, 'b>(
state: &'b mut i32,
) -> impl FnMut(&'a str) -> &'static str + 'b
where
'a: 'b,
{
|s| "hi"
}

然而,如果没有参数使用'a,那么'a应该是一个更高阶的特征界:

fn foo<'b>(
state: &'b mut i32,
) -> impl for<'a> FnMut(&'a str) -> &'static str + 'b {
|s| "hi"
}

Fn家族的特征是特殊的,因为它们允许您完全省略生命周期(遵循与fn签名相同的省略规则),所以这是等效的:

fn foo<'b>(
state: &'b mut i32,
) -> impl FnMut(&str) -> &'static str + 'b {
|s| "hi"
}

相关内容

  • 没有找到相关文章

最新更新