如何在没有递归的情况下删除此mandelbrot函数中的可变变量?

时间:2016-10-26 10:42:30

标签: rust immutability

以下函数计算mandelbrot fractal初始值“逃逸”所需的轨道数:

extern crate num;

fn mandel_escape(x: f32, y: f32, limit: f32, orbits: u32) -> Option<u32> {
    let c = num::complex::Complex32::new(x, y);
    let mut z = c;
    for i in 0 .. orbits {
        z = z * z + c;
        if z.norm_sqr() > limit { return Some(i); }
    }
    None
}

据我所知,Rust中没有保证尾调用优化。如何在没有递归的情况下删除此函数中的可变变量?

1 个答案:

答案 0 :(得分:2)

这是不可能的。

您需要在某个时刻为每次迭代创建z的值。所以要么你有一个可变的位置来存储每一个,要么你需要所有的空间。

但是,您可以隐藏迭代器内的可变性:

struct MandelIterator {
    c: f32,
    z: f32,
}

fn mandel_iter(c: f32) -> MandelIterator {
    MandelIterator { c: c, z: 0.0 }
}

impl Iterator for MandelIterator {
    type Item = f32;
    fn next(&mut self) -> Option<Self::Item> {
        self.z = self.z * self.z + self.c;
        Some(self.z)
    }
}

fn mandel_escape(x: f32, y: f32, limit: f32, orbits: usize) -> Option<usize> {
    for (i, z) in mandel_iter(x*y).enumerate().take(orbits) {
        if z.abs() > limit { return Some(i); }
    }
    None
}

fn main() {
    println!("{:?}", mandel_escape(1.00001, 1.00001, 40999.0, 4));
}