Hello, Rustaceans! I'm working with async traits and need to define an async function within a trait that takes a reference parameter. Given the lifetime constraints and the async_trait
macro's handling of lifetimes, is there a recommended approach to achieve this? Are there best practices for passing non-'static
references to async trait functions, or should I consider alternative strategies to manage lifetimes effectively in async contexts?
If you are using Rust 1.75—which stabilized async fn
in traits—or newer, you could avoid the problematic 'async_trait
lifetime by not using the async_trait
crate:
pub trait Trait1<T>: Sized {
async fn from2(value: T) -> Self;
}
fn main() {
struct MyNumber(u32);
impl<'a> Trait1<&'a str> for MyNumber {
async fn from2(value: &'a str) -> Self {
let num = value.parse::<u32>().unwrap_or(0);
MyNumber(num)
}
}
let num = MyNumber::from2("42");
// println!( "Converted: {}", num.0 );
}
From the 1.75 release notes @jofas linked, be cautious of the limitations in section "async fn
in public traits" where the auto Send
bound is not automatically added to return type of the desugared async
trait method. The compiler would issue a warning
warning: use of
async fn
in public traits is discouraged as auto trait bounds cannot be specified
because retroactively adding it would be a breaking API change. In contrast, the async_trait
adds the Send
bound on the return type by default. If the trait is intended to work in a multithreaded environment, consider explicitly desugaring the async
trait method and add a Send
bound on the return type.