Reputation: 901
What is a good way to initialize the vector, without the mut
keyword, given that the vector will be immutable after the initialization?
For example:
// 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
Otherwise, to mark padded
mut
, simply to initialize it, seems to me a waste of immutability, since I cannot enforce it after the initialization.
Upvotes: 2
Views: 902
Reputation: 3057
There are 3 ways:
let v: Vec<i32> = std::iter::once(1).chain(
nums.iter().copied()
)
.collect();
let v = {
let mut v: Vec<i32> = vec![0; len_p];
v[0] = 1;
v[len_n + 1] = 1;
for (&src, dst) in nums.iter().zip(v[1..].iter_mut()){
*dst = src;
}
v
}
let mut v: Vec<i32> = vec![0; len_p];
v[0] = 1;
v[len_n + 1] = 1;
for (&src, dst) in nums.iter().zip(v[1..].iter_mut()){
*dst = src;
}
// Rebind to immutable variable
let v = v;
// Cannot mutate here
Upvotes: 3
Reputation: 70277
A common idiom seen in Rust is to introduce a local scope for just this purpose.
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
};
Inside the nested scope, we have a local variable called tmp
which is mutable. Then, when we get to the end of that scope, we pass ownership of that vector to the immutable variable padded
. The compiler is free to (and likely will) optimize out any actual movement that's happening, and this will compile to something as efficient as what you wrote. But from the borrow checker's perspective, tmp
is mutable and padded
is immutable, as desired. Once tmp
goes out of scope, there's no way to modify padded
anymore.
Remember, the owner of a value always determines whether or not that value is mutable, so when you pass ownership to someone else, they're free to change the mutability of the value upon taking ownership.
Upvotes: 6