2个版本
0.0.2 | 2020年5月1日 |
---|---|
0.0.1 | 2020年5月1日 |
#640 in 进程宏
8KB
105 代码行
TCO
TCO是一个尾调用优化库。它是一个可以附加到项函数上的概念属性宏,如果它们处于尾调用格式,则可以对其进行优化。
限制
它不是很智能。
它实际上并没有验证函数是否为尾调用函数。
它只适用于自由函数(例如,不在impl块中的fn foo(bar: Bar) -> u32
)。
它可能存在传递非复制参数的问题。
它未使用引用进行测试。
它不支持相互递归。
它只支持函数参数中的基本模式(不支持元组解构)。
它不能将非尾调用函数转换为尾调用函数。
需要帮助
这只是一个概念证明。我很乐意帮助完善它。
替代方案
- (tramp)https://docs.rs/tramp/0.3.0/tramp/
- (async-recursion)https://docs.rs/async-recursion/0.3.1/async_recursion/
示例
说得够多了,让我们看看示例!
同步示例:阶乘
#[tco::rewrite]
fn fac_with_acc(n: u128, acc: u128) -> u128 {
if n > 1 {
fac_with_acc(n - 1, acc * n)
} else {
acc
}
}
展开为
fn fac_with_acc(n: u128, acc: u128) -> u128 {
let mut n = n;
let mut acc = acc;
'__tco_loop: loop {
return {
if n > 1 {
{
let __tco_0 = (n - 1, acc * n);
n = __tco_0.0;
acc = __tco_0.1;
continue '__tco_loop;
}
} else {
acc
}
};
}
}
异步示例:阶乘
#[tco::rewrite]
async fn fac_with_acc(n: u128, acc: u128) -> u128 {
if n > 1 {
fac_with_acc(n - 1, acc * n).await
} else {
acc
}
}
展开为
async fn fac_with_acc(n: u128, acc: u128) -> u128 {
let mut n = n;
let mut acc = acc;
'__tco_loop: loop {
return {
if n > 1 {
{
let __tco_0 = (n - 1, acc * n);
n = __tco_0.0;
acc = __tco_0.1;
continue '__tco_loop;
}
} else {
acc
}
};
}
}
如果没有tco::rewrite属性,您将得到以下错误
error[E0733]: recursion in an `async fn` requires boxing
--> $DIR/await_no_tco.rs:6:46
|
6 | async fn fac_with_acc(n: u128, acc: u128) -> u128 {
| ^^^^ recursive `async fn`
|
= note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`
依赖
~1.5MB
~36K SLoC