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