为何GAT、生命周期与async组合要求`T: 'static`?
问题:Connection trait 中生命周期导致的
T 生命周期不足错误 以下代码在do_the_thing()函数中报错,提示T的生命周期不足:
use std::future::Future; trait Connection: Send { type ExecFut<'a>: Future<Output = ()> + Send where Self: 'a; fn transaction<F>(&mut self, _f: F) where F: for<'a> FnOnce(&'a mut Self) -> Box<dyn Future<Output = ()> + Send + 'a> + Send, { unimplemented!() } fn execute<'a>(&'a mut self) -> Self::ExecFut<'a> { unimplemented!() } } fn do_the_thing<T: Connection>(connection: &mut T) { connection.transaction(|conn| { Box::new(async move { conn.execute().await; }) }); }
对应的错误信息:
error[E0310]: the parameter type `T` may not live long enough --> src/main.rs:22:9 | 22 | / Box::new(async move { 23 | | conn.execute().await; 24 | | }) | |__________^ ...so that the type `T` will meet its required lifetime bounds | help: consider adding an explicit lifetime bound... | 20 | fn do_the_thing<T: Connection + 'static>(connection: &mut T) { | +++++++++
我认为这里不该有'static的隐含约束,几乎所有内容都受'a约束,T的生命周期应该始终长于'a,但显然我漏了某些细节。
我还试了几个无效的“解决方案”:
- 按编译器提示添加
'static约束虽然能绕过错误,但实际场景中需要使用带非'static生命周期的Connection实例,这个方案不可行。 - 移除
dyn Future上的Send约束后代码能编译,但我完全搞不懂原因。 - 将函数改成非泛型,使用非
'static的Connection实例也能编译,这和编译器给出的错误矛盾。
这段是简化后的示例代码,实际需求来自diesel-async crate中的AsyncConnection相关代码结构,希望搞清楚这个核心问题的原因和可行解决方案,再适配到真实场景中。
内容的提问来源于stack exchange,提问作者kmdreko
相关产品推荐
相关产品推荐

