#async-trait #async #heap-memory #traits #heap-allocation #future #fork

已删除 async-trait-fn

具有有用附加功能的 async-trait 的分支

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

Download history 2299/week @ 2024-03-13 2563/week @ 2024-03-20 2506/week @ 2024-03-27 1337/week @ 2024-04-03 1517/week @ 2024-04-10 1568/week @ 2024-04-17 1958/week @ 2024-04-24 977/week @ 2024-05-01 3047/week @ 2024-05-08 2207/week @ 2024-05-15 2156/week @ 2024-05-22 1881/week @ 2024-05-29 1751/week @ 2024-06-05 1672/week @ 2024-06-12 1923/week @ 2024-06-19 2205/week @ 2024-06-26

7,985 每月下载量

MIT/Apache

56KB
1K SLoC

async-trait-fn

Cargo Crates.io

这是一个备受赞誉的 async-trait crate 的分支。此 crate 为 async-trait 添加了两个实验性属性,这些属性可以应用于异步 trait 方法和相关函数,以避免堆内存分配。

  • 具有 unboxedunboxed_simple 属性的异步 trait 方法或相关函数的返回类型为 impl Future<..>,而不是 Box<dyn Future<..>>
  • 由于 Rust 泛型关联类型的已知错误,这些属性在大型软件产品中使用时存在许多限制:例如,9571990696

请注意,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_simpleunboxed 完全相同,只是将所有生命周期界限和参数替换为单个固定的生命周期:'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