首页 > 解决方案 > 鉴于向量在初始化后将是不可变的,如何在 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

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

标签: vectorrust

解决方案


在 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
};

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

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


推荐阅读