7 个版本
0.1.5 | 2022 年 12 月 1 日 |
---|---|
0.1.4 | 2022 年 12 月 1 日 |
0.1.3 | 2022 年 8 月 10 日 |
0.0.0 | 2022 年 8 月 5 日 |
#1141 在 Rust 模式
23KB
271 行
因此,你有一个很好的 async fn
,并且你想要将返回的未来存储在结构体中。不需要装箱或动态调度:你静态地知道类型。你只需要...
name-it
#[name_it(Test)]
async fn add(x: i32, y: i32) -> i32 {
do_something_very_async().await;
x + y
}
let foo: Test = add(2, 3);
assert_eq!(block_on(foo), 5);
函数属性(包括文档注释)被保留。创建的类型将与函数本身的可见性相同,大小、对齐以及 Send
和 Sync
与原始未来相同。
MSRV 是 1.61。据我所知,它无法在旧版本的 Rust 上运行。
安全性
我不认为这会有不安全的地方。Miri 喜欢它,我与其他人讨论过,所有不安全的部分都不是特别严重。
Miri 不再喜欢它了,见 这个构建运行。
该问题已在 UCG 仓库中报告以供讨论: https://github.com/rust-lang/unsafe-code-guidelines/issues/380
为了解决一些特定的问题
-
将任何类型转换为
MaybeUninit<u8>
数组,并将其转换回来目前被认为是安全的。 -
生成的类型的对齐被保留。
-
生成的类型在析构函数中从不解引用使用,也从不移动到析构函数中。
-
生成的类型的生命周期与每个输入的生命周期绑定,因此不可能发生 use-after-free。
尽管如此,我无法完全确定它是否安全。如果您发现任何安全性问题,请提交问题。
限制
绝对
-
它不能直接应用于方法或关联函数。您可以移动方法的主体到一个自由函数,并将方法作为一个薄包装器。
-
它不支持具有 类型 泛型的函数。这是由于在 const 上下文中使用泛型的限制造成的。
(可能) 可解
-
它目前还不支持显式 生命周期 泛型。它没有根本问题,只是需要在宏中实现(需要帮助)!
-
所有参数都必须是简单标识符(因此不允许像这样
(x, y): (i32, i32)
的结构)。再次强调,这应该是可行的,只是尚未实现。 -
尽管底层技巧可以在大多数
impl Trait
类型上工作,但这个crate只为async fn
实现了它。不清楚如何使宏适用于任何特质。
那么关于 stackfuture
呢?
微软的 stackfuture 实际上采取了类似的方法来解决此问题。主要区别
-
name-it
会自动推断类型大小、对齐和自动特质。stackfuture
具有固定对齐,手动指定大小,并且始终是Send + !Sync
。 -
stackfuture
不使用宏,因此对工具更友好,并支持泛型。它还可以直接用于方法,包括特质方法。 -
stackfuture
使用动态分派。name-it
完全是静态的,没有动态函数调用。
许可证
蓝橡树模型许可证 1.0.0 是一种宽泛的非版权许可证。如果你对罕见的许可证感到不安,你可以使用 Apache 2.0。
文件 tests/futures-*
来自于 futures-rs 项目。
依赖关系
~1.5MB
~35K SLoC