Does destructuring a tuple make the variable mutable?
This is the code snippet that confuses me:
let tup = ("duck", 11, true);
let (_, data, ..) = tup;
println!("data: {}", data);
let (_, .., data) = tup; // I expected that this is not available
println!("data: {}", data);
data = "what"; // like this, but then this one why not?
let
actually defines a new variable. So in your code, two data
variables exist, one created by the first let
, and one created by the second let
.
That said, the second let data
shadows the name of the first one, making the first one exist in the background somewhere but being inaccessible because its name has been reused by the second one.
This is also the reason why you don't need to declare the first data
as mut
- you never mutate it. It still exists in the background, the new data
variable just stole the name.
The last line fails because data
now refers to the second data
object, which is a boolean. And you cannot assign strings to booleans. Apart of that, it isn't declared mut
, so even if you wrote data = false;
, it would fail to compile.
You can replace the last line with let data = "what";
, then it will compile. But then you have three data
variables now, with the previous two being shadowed.
To demonstrate that it is actually shadowed, here is a little example. It temporarily shadows the variable inside of the nested scope; after the scope the previous variable is reachable again because the nested one got dropped:
fn main() {
let tup = ("duck", 11, true);
let (_, data, ..) = tup;
println!("data: {}", data);
{
let (_, .., data) = tup;
println!("data: {}", data);
}
println!("data: {}", data);
}
data: 11
data: true
data: 11