在 C 编程语言中,很容易出现尾递归:
int foo(...) {
return foo(...);
}
Run Code Online (Sandbox Code Playgroud)
只需返回递归调用的返回值即可。当这种递归可能重复一千次甚至一百万次时,这一点尤其重要。它会在堆栈上使用大量内存。
现在,我有一个 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),
}
}
Run Code Online (Sandbox Code Playgroud)
(这是一个最小的例子,真正的例子更复杂,但它抓住了主要思想)
这里,递归调用的返回值按原样返回,但是:
它是否保证 Rust 编译器会应用尾递归?
例如,如果我们声明了一个像 a 这样需要销毁的变量,std::Vec它会在递归调用之前(允许尾递归)还是在递归调用返回之后(禁止尾递归)被销毁?
我在Rust中尝试了一个递归因子算法.我使用这个版本的编译器:
rustc 1.12.0 (3191fbae9 2016-09-23)
cargo 0.13.0-nightly (109cb7c 2016-08-19)
Run Code Online (Sandbox Code Playgroud)
码:
extern crate num_bigint;
extern crate num_traits;
use num_bigint::{BigUint, ToBigUint};
use num_traits::One;
fn factorial(num: u64) -> BigUint {
let current: BigUint = num.to_biguint().unwrap();
if num <= 1 {
return One::one();
}
return current * factorial(num - 1);
}
fn main() {
let num: u64 = 100000;
println!("Factorial {}! = {}", num, factorial(num))
}
Run Code Online (Sandbox Code Playgroud)
我收到了这个错误:
$ cargo run
thread 'main' has overflowed its stack
fatal runtime error: stack overflow
error: Process didn't …Run Code Online (Sandbox Code Playgroud)