Async 工作组很高兴地宣布 RFC 3654 返回类型记法 (RTN) 已准备好在 nightly Rust 上进行测试。在本文中,我们将简要描述该功能。
背景故事
Rust 1.75 稳定了 trait 中的 async fn (AFIT) 和 trait 中返回位置的 impl Trait (RPITIT)。这些会被解糖为匿名的泛型关联类型 (GATs)。然而,与 GATs 不同的是,这些类型的用户不能使用 where
子句来进一步限制这些返回类型。这被称为 “Send bound” 问题,因为它经常影响 async 生态系统中 future 的 Send
bound。
示例
考虑一个 trait Foo
,其中有一个 method
方法返回类型为 impl Future<Output = ()>
。我们想编写一个函数来调用 method
并将 future 衍生到另一个线程上。
具体来说,我们可能不想限制 Foo
的 *声明*,因为在声明中更改它会限制 Foo
的 *所有* 实现。
因此,在稳定版 Rust 中,在使用 AFIT 或 RPITIT 时,我们无法表达这种限制。相比之下,如果直接使用 GAT,我们今天就可以表达这种限制
然而,使用 GATs 意味着 Foo
的实现者必须明确写出返回类型,type MethodFuture = ...
,而当返回类型是匿名的、无法命名的 Future
类型时,这(还)不起作用!
解决方案
在 RFC 3654 中,我们引入了返回类型记法 (RTN)。这将允许我们编写 where
子句 bound 来限制使用 trait 中的 async fn (AFIT) 和 trait 中返回位置的 impl Trait (RPITIT) 的函数和方法的返回类型。扩展上面的例子,RTN 允许我们编写
限制
目前,RTN 仅适用于使用以下特征的 trait 关联函数和方法(具有生命周期泛型,而非 const 或类型泛型):
- trait 中的 async fn (AFIT),或
- trait 中返回位置的 impl Trait (RPITIT),其中 impl Trait 是最外层的返回类型,即
-> impl Trait
,而不是-> Box<impl Trait>
。
这些限制在 RFC 3654 中有更详细的描述。
我如何提供帮助?
我们非常希望您能在最新的 Rust nightly 编译器上测试此功能1。
具体来说,我们希望您能找出那些您不必要地使用 + Send
或类似 bound 限制了 trait 定义的 trait
// Instead of writing a trait like:
// Write this:
// And then at the call site, add:
同样,我们希望您能找出目前出于相同原因而返回 GATs 的 trait
// Instead of writing this in the trait and call site:
// Write this:
然而,请注意,我们尚不支持在类型位置使用 RTN。因此,虽然在第一个版本中您可以编写
但在第二个版本中,您还不能编写
我们很高兴听到您在使用中遇到的任何限制。
我们很高兴 RTN 能让在 Send
-bound 繁重的 async Rust 生态系统中使用 trait 中的 async fn (AFIT) 变得更容易。
一如既往,请查阅 RFC 本身,了解我们确定此设计的详细解释,特别是常见问题解答和基本原理。