3 个不稳定版本
0.1.3 | 2022年8月10日 |
---|---|
0.1.0 | 2022年8月8日 |
0.0.0 | 2022年8月5日 |
#17 in #visibility
在 name-it 中使用
10KB
219 行
所以,你有一个很好的 async fn
,并想将返回的 future 存储在结构体中。不需要装箱或动态分发:你静态地知道类型。你只需要...
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);
保留函数属性(包括文档注释)。创建的类型将具有与函数相同的可见性,相同的大小、对齐,以及与原始 future 相同的 Send
和 Sync
。
MSRV 是 1.61。据我所知,使其在旧版 Rust 版本上工作是不可能的。
安全性
我不明白为什么会不安全。Miri 很喜欢它,我与其他人讨论过,所有不安全的部分都不特别恶劣。
Miri 现在不喜欢它了,请参阅 这个构建运行。
这个问题已在 UCG 仓库中报告以供讨论:https://github.com/rust-lang/unsafe-code-guidelines/issues/380
为了解决一些特定的担忧
-
将任何类型转换为
MaybeUninit<u8>
的数组并返回目前被认为是安全的。 -
生成的类型的对齐被保留。
-
生成的类型永远不会在析构函数中未锁定使用,也永远不会在析构函数中移动。
-
生成的类型的生命周期与每个输入的生命周期绑定,因此不可能发生使用后释放。
尽管如此,我无法完全确信它仍然是安全的。如果您发现任何安全性问题,请提交问题。
限制
绝对
-
它不能直接应用于方法或关联函数。你可以将方法的主体移动到自由函数中,并使你的方法成为一个薄的包装器。
-
它不支持带有 类型 泛型的函数。这是由于在 const 上下文中使用泛型的限制造成的。
(可能) 可解
-
它目前也不支持显式的 生命周期 泛型。它没有根本问题,只需在宏中实现即可(需要帮助!)。
-
所有参数必须是简单标识符(因此,像
(x, y): (i32, i32)
这样的格式是不允许的)。再次强调,这应该可以实现,只是目前还没有实现。 -
虽然底层技巧可以在大多数
impl Trait
类型上工作,但这个包只为async fn
实现了它。不清楚如何使宏对任何特质都有效。
那么 stackfuture
呢?
微软的 stackfuture 确实采取了类似的方法来解决此问题。主要区别
-
name-it
自动推断类型大小、对齐和自动特质。stackfuture
有固定的对齐方式,手动指定大小,并且始终是Send + !Sync
。 -
stackfuture
不使用宏,因此对工具更友好,并支持泛型。它还可以直接用于方法,包括特质方法。 -
stackfuture
使用动态分发。name-it
完全静态,没有动态函数调用。
许可证
Blue Oak Model License 1.0.0 是一种宽容的、非版权许可。如果您不喜欢罕见的许可,您可以使用 Apache 2.0。
文件 tests/futures-*
来自 futures-rs 项目。
依赖关系
~1.5MB
~36K SLoC