鉴于向量在初始化后不可变,如何在 Rust 中正确初始化向量?

Leo*_*eon 2 vector rust

mut鉴于向量在初始化后将不可变,在没有关键字的情况下初始化向量的好方法是什么?

例如:

// nums is a `i32` vector(Vec<i32>)
// here is to pad two 1s with both ends
let mut padded: Vec<i32> = vec![0; len_p];
padded[0] = 1;
padded[len_n + 1] = 1;
for (idx, &num) in nums.iter().enumerate(){
    padded[idx + 1] = num;
}
// `padded` will be read-only/immutable ever since
Run Code Online (Sandbox Code Playgroud)

否则,标记padded mut,简单地初始化它,在我看来是对不变性的浪费,因为我无法在初始化后强制执行它。

Sil*_*olo 6

Rust 中常见的习惯用法是为此目的引入本地作用域。

let padded: Vec<i32> = {
  let mut tmp: Vec<i32> = vec![0; len_p];
  tmp[0] = 1;
  tmp[len_n + 1] = 1;
  for (idx, &num) in nums.iter().enumerate(){
    tmp[idx + 1] = num;
  }
  tmp
};
Run Code Online (Sandbox Code Playgroud)

在嵌套作用域内,我们有一个名为的局部变量,tmp它是可变的。然后,当我们到达该范围的末尾时,我们将该向量的所有权传递给不可变变量padded。编译器可以自由地(并且可能会)优化正在发生的任何实际运动,并且这将编译成与您编写的内容一样高效的内容。但从借用检查器的角度来看,tmp它是可变的并且padded是不可变的,如所期望的那样。一旦tmp超出范围,就无法padded再修改。

请记住,值的所有者始终决定该值是否可变,因此当您将所有权传递给其他人时,他们可以在获得所有权后自由更改值的可变性。

  • 如果 `ppped` 应该永远不可变(即不移动,然后在其他地方变异),那么通过在最后调用 `tmp.into_boxed_slice()` 使其类型为 `Box&lt;[i32]&gt;` 也可能是一个好主意的范围。 (5认同)