更有效地初始化数组保持结构

时间:2017-05-25 13:50:00

标签: arrays for-loop struct rust

我有以下代码:

const N: usize = 10000;
const S: usize = 7000;

#[derive(Copy, Clone, Debug)]
struct T {
    a: f64,
    b: f64,
    f: f64
}

fn main() {
    let mut t: [T; N] = [T {a: 0.0, b: 0.0, f: 0.0}; N];

    for i in 0..N {
        t[i].a = 0.0;
        t[i].b = 1.0;
        t[i].f = i as f64 * 0.25;
    }

    for _ in 0..S {
        for i in 0..N {
            t[i].a += t[i].b * t[i].f;
            t[i].b -= t[i].a * t[i].f;
        }
        println!("{}", t[1].a);
    }
}

我不确定为什么必须以这种方式初始化数组t。第一个for循环用于将包含struct的数组初始化为各自的值。

当我尝试直接用数组省略初始化时:

let mut t: [T; N];

我收到以下错误:

  

错误[E0381]:使用可能未初始化的变量:t

所有for循环都是这样的,我只是想知道数组是否有更聪明的方法,并且它是用第一个for循环初始化的。

2 个答案:

答案 0 :(得分:7)

  

我不确定为什么必须以这种方式初始化数组t

因为Rust不会让您(完全或部分)接触未初始化的值。编译器不够智能,无法证明循环肯定初始化所有内容,所以它只是禁止它。

现在,优化器是另一回事。 可以注意到初始化是多余的并且在理论上跳过它......它似乎没有使用该代码和当前编译器。这就是优化。

  

我只是想知道数组是否有更聪明的方法,并且使用第一个for循环进行初始化。

聪明的方法是让代码保持原样。从统计上讲,它不太可能成为瓶颈。如果分析表明 是瓶颈,那么您可以使用uninitialised。但请注意,如果您使用错误,这样做会导致未定义的行为。虽然不是详尽的列表,但绝对可以避免在任何非Copy的类型上使用它。

如果您需要使用它,我强烈建议您还调整第一个循环,以便忘记在结构中初始化元素一个字段:

    let mut t: [T; N] = unsafe { ::std::mem::uninitialized() };

    for (i, e) in t.iter_mut().enumerate() {
        *e = T {
            a: 0.0,
            b: 1.0,
            f: i as f64 * 0.25,
        }
    }

答案 1 :(得分:2)

您可以使用std::mem::uninitialized()。但请注意,它被认为是不安全的,需要标记为:

let mut t: [T; N] = unsafe { std::mem::uninitialized() };

如上述文件中所述:

  

这对FFI函数和初始化数组有时很有用,   但通常应该避免。