Rust编写接收异步函数参数的异步函数时生命周期编译报错求解
问题解答
1、为什么编译器提示期望和找到的类型完全一致却仍报错?
报错中展示的两个类型看起来完全一致,是因为编译器默认没有打印出隐藏的生命周期参数。实际foo作为异步函数,返回的Future会捕获输入的&mut i32引用,Future本身的生命周期和这个引用的生命周期是强绑定的。而你原代码的泛型约束里,Fut被声明为独立于输入参数生命周期的固定类型,相当于要求不管传入的&mut i32生命周期是什么,返回的都是同一个Fut类型,这和foo实际返回类型的隐式生命周期约束冲突,因此触发报错。
2、报错中提到的「空生命周期」是什么?是不是指代'_,有没有特殊含义?
你理解的没错,这里的「空生命周期」就是匿名生命周期'_,它是Rust中未明确命名的生命周期占位符。这个报错里的空生命周期指代没有和输入参数绑定的泛型生命周期约束,因为你原代码的约束中没有声明Fut和输入&mut i32的生命周期关联,编译器就会用这个空生命周期指代无绑定的生命周期占位,提示你当前的生命周期约束无法满足关联要求。
3、如何修改代码才能正常编译?
修改核心是明确声明返回的Future和输入的&mut i32引用的生命周期绑定,有两种常用实现方案:
方案1:使用Nightly Rust特性(写法更简洁)
启用impl_trait_in_assoc_type特性即可直接在约束中声明生命周期关联,代码如下:
#![feature(impl_trait_in_assoc_type)] use std::future::Future; async fn run_another_async_fn<F>(f: F) where F: for<'a> FnOnce(&'a mut i32) -> impl Future<Output = ()> + 'a, { let mut i = 42; println!("running function"); f(&mut i).await; println!("ran function"); } async fn foo(i: &mut i32) {} async fn bar() { run_another_async_fn(foo); }
方案2:稳定版Rust实现
稳定版暂时不支持直接在约束中写带生命周期的impl Future,可以通过装箱Future的方式实现:
use std::future::Future; use std::pin::Pin; async fn run_another_async_fn<F>(f: F) where F: for<'a> FnOnce(&'a mut i32) -> Pin<Box<dyn Future<Output = ()> + 'a>>, { let mut i = 42; println!("running function"); f(&mut i).await; println!("ran function"); } async fn foo(i: &mut i32) {} // 给foo加一层包装,返回装箱的Future fn foo_wrapper(i: &mut i32) -> Pin<Box<dyn Future<Output = ()> + '_>> { Box::pin(foo(i)) } async fn bar() { run_another_async_fn(foo_wrapper); }
内容的提问来源于stack exchange,提问作者Phil Frost
相关产品推荐
相关产品推荐

