19 个版本
0.1.77 | 2024 年 1 月 3 日 |
---|---|
0.1.75 | 2023 年 12 月 28 日 |
0.1.74 | 2023 年 10 月 15 日 |
0.1.72 | 2023 年 7 月 24 日 |
0.1.58 | 2022 年 10 月 19 日 |
#34 在 #heap-memory
7,985 每月下载量
56KB
1K SLoC
async-trait-fn
这是一个备受赞誉的 async-trait crate 的分支。此 crate 为 async-trait 添加了两个实验性属性,这些属性可以应用于异步 trait 方法和相关函数,以避免堆内存分配。
- 具有
unboxed
或unboxed_simple
属性的异步 trait 方法或相关函数的返回类型为impl Future<..>
,而不是Box<dyn Future<..>>
。 - 由于 Rust 泛型关联类型的已知错误,这些属性在大型软件产品中使用时存在许多限制:例如,95719 和 90696。
请注意,async-trait 的主要作者 不想添加此类选项,因此此分支不会合并到上游。
有关 async-trait 的更多信息,请参阅 async-trait。
示例
unboxed
通过为方法或相关函数添加泛型关联类型,将异步 trait 方法或相关函数转换为返回 impl Future<..>
的同步函数。
use async_trait_fn::{async_trait, unboxed_simple};
#[async_trait]
pub trait SelfToUsize {
#[unboxed]
async fn get(&self) -> usize;
}
#[async_trait]
impl SelfToUsize for u32 {
#[unboxed]
async fn get(&self) -> usize {
*self as usize
}
}
编译器生成以下代码。
pub trait SelfToUsize {
fn get<'life0, 'async_trait>(&'life0 self) -> Self::RetTypeOfGet<'life0, 'async_trait>
where
'life0: 'async_trait,
Self: 'async_trait;
type RetTypeOfGet<'life0, 'async_trait>: ::core::future::Future<Output = usize>
+ ::core::marker::Send
+ 'async_trait
where
'life0: 'async_trait,
Self: 'async_trait,
Self: 'life0;
}
impl SelfToUsize for u32 {
fn get<'life0, 'async_trait>(&'life0 self) -> Self::RetTypeOfGet<'life0, 'async_trait>
where
'life0: 'async_trait,
Self: 'async_trait,
{
async move {
if let ::core::option::Option::Some(__ret) = ::core::option::Option::None::<usize> {
return __ret;
}
let __self = self;
let __ret: usize = { *__self as usize };
#[allow(unreachable_code)]
__ret
}
}
type RetTypeOfGet<'life0, 'async_trait> = impl ::core::future::Future<Output = usize>
+ ::core::marker::Send
+ 'async_trait
where
'life0: 'async_trait,
Self: 'async_trait,
Self: 'life0 ;
}
unboxed_simple
与 unboxed
完全相同,只是将所有生命周期界限和参数替换为单个固定的生命周期:'async_trait
。当带有 unboxed
属性的代码无法编译时,unboxed_simple
可能会提供帮助。
use async_trait_fn::{async_trait, unboxed_simple};
#[async_trait]
pub trait AddOther {
#[unboxed_simple]
async fn add<'s, 'o>(&'a self, other: &'o usize) -> usize;
}
#[async_trait]
impl AddOther for u32 {
#[unboxed_simple]
async fn add<'s, 'o>(&'a self, other: &'o usize) -> usize {
(*self as usize) + *other
}
}
上述代码展开为以下代码;所有生命周期参数都被替换为 'async_trait
。
pub trait AddOther {
fn add<'async_trait>(
&'async_trait self,
other: &'async_trait usize,
) -> Self::RetTypeOfAdd<'async_trait>
where
Self: 'async_trait;
type RetTypeOfAdd<'async_trait>: ::core::future::Future<Output = usize>
+ ::core::marker::Send
+ 'async_trait
where
Self: 'async_trait,
Self: 'async_trait;
}
impl AddOther for u32 {
fn add<'async_trait>(
&'async_trait self,
other: &'async_trait usize,
) -> Self::RetTypeOfAdd<'async_trait>
where
Self: 'async_trait,
{
async move {
if let ::core::option::Option::Some(__ret) = ::core::option::Option::None::<usize> {
return __ret;
}
let __self = self;
let other = other;
let __ret: usize = { (*__self as usize) + *other };
#[allow(unreachable_code)]
__ret
}
}
type RetTypeOfAdd<'async_trait> = impl ::core::future::Future<Output = usize>
+ ::core::marker::Send
+ 'async_trait
where
Self: 'async_trait,
Self: 'async_trait;
}
依赖项
~280–730KB
~17K SLoC