有时,在循环中为固定大小的数组创建新值很有用:
fn foo(u: f64) -> [f64; 3] {
let mut ret = [-1.0; 3]; // -1 is never used!
for i in 0..3 {
ret[i] = some_calculation(u, i);
}
return ret;
}
虽然这可行,但创建一个填充从未使用过的值的数组有点弱。
另一种方法是手动展开,但这对于较大的固定大小数组或当表达式比给出的示例更复杂时不太好:
fn foo(u: f64) -> [f64; 3] {
return [
some_calculation(u, 0),
some_calculation(u, 1),
some_calculation(u, 2),
];
}
Rust 是否提供了一种方法来执行与 Python 的列表理解大致相同的操作?
fn foo(u: f64) -> [f64; 3] {
return [some_calculation(u, i) for i in 0..3];
}
我是一个初学者,对迭代器的经验很少。
最佳答案
Rust 在默认模式下保证内存安全(在 unsafe
block 之外)。
为了做到这一点,它必须保证不会访问任何未初始化的内存,这意味着(对于数组)无论发生什么情况它们都被完全初始化。
聪明的分析可以检查你的循环是否会完全初始化它,但可能无法证明它在更复杂的情况下有效,因此体验会不一致,并且当函数中的简单更改突然导致由于编译器无法再证明它有效,因此您必须返回数组并完全初始化它。
因此,Rust 采用了以下方法:
- 要求用户完全初始化数组(通过提供可复制的值)
- 依靠优化器消除冗余写入
如果第二步在特定设置中失败,用户可以使用 unsafe { std::men::uninitialized() }
告诉编译器它会自行保证它已完全初始化。
这种方法总是安全的,通常也很快,...并且当您不幸无法使用 Copy
类型时,会非常烦人。在后一种情况下,一个简单的策略是首先构建一个 Vec,然后使用简单的 for 循环将其元素移动到数组中,希望优化器应该消除所有之后不必要的东西。
关于arrays - 如何最好地返回固定大小的数组,而无需创建具有虚拟值或手动展开的数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39324463/