在C编程语言中,很容易使用tail recursion:
int foo(...) {
return foo(...);
}
只需返回,就像递归调用的返回值一样。当此递归可能重复一千甚至一百万次时,这一点尤其重要。它会使用很多堆栈上的内存。
现在,我有一个Rust函数,可以递归地调用它一百万次:
fn read_all(input: &mut dyn std::io::Read) -> std::io::Result<()> {
match input.read(&mut [0u8]) {
Ok ( 0) => Ok(()),
Ok ( _) => read_all(input),
Err(err) => Err(err),
}
}
((这是一个最小的示例,真实的示例更复杂,但它捕获了主要思想)
这里,递归调用的返回值按原样返回,但是:
是否保证Rust编译器将应用尾递归?
例如,如果我们声明一些需要像std::Vec
一样销毁的变量,它将在递归调用之前(允许尾部递归)或在递归调用返回之后(禁止尾部递归)销毁。 ?
tail position(基本上是该函数的最后一条语句)中调用递归函数,就可以保证Tail calls。 尽管优化器可以 另请参见: