4 ms·
Can I write let x = 1; let x = x + 1; ?
by tormeh 10y ago
Can I write
let x = 1;
let x = x + 1;
?
- steveklabnik 10y agoYes.
- tormeh 10y agoAnd is the behavior exactly the same as it would be if I omitted "let" on the second code line? If the answer is yes, isn't it just mutability with different syntax then? I would guess shadowing wouldn't affect values shared with a different thread, because it's technically a new value, but in single-thread use it would be equivalent to assignment.
- solidsnack9000 10y ago> I would guess shadowing wouldn't affect values shared with a different thread... That is actually a big deal, though.
- yokohummer7 10y agoIt doesn't have the same semantics, because even after introducing the new variable, it is still immutable. So you cannot accidentally modify the new variable. e.g., let x = 1; let x = x + 1; x = 99; // Error: you can't accidentally modify the immutable variable `x` let mut x = 1; x = x + 1; x = 99; // Ok You can even turn back a mutable varaible into an immutable variable, like this: let mut x = 1; x = x + 1; let x = x; x = 99; // Error: `x` became immutable This can be useful to "pin" the variable after a large number of calculations done to it.
- steveklabnik 10y agoThe behavior is not the same. It's a new variable, entirely. So you'll have two integers on the stack, one of them is not accessible any more. You can see this difference if you add a scope around the second x, and then print the value of the original x after it goes out of scope. Consider this program: fn main() { let x = 5; let r1 = &x; let x = x + 1; let r2 = &x; println!("r1: {:p}", r1); println!("r2: {:p}", r2); } This will print something like r1: 0x7fff955e3dfc r2: 0x7fff955e3dec Note that while you can't access the original x, it's still there, and references to it still work. Because the value of x was copied, not mutated. Also, given compiler details like SSA, I'd argue that in a certain sense, mutation is similar to this, rather than this being similar to mutation...
- kibwen 10y ago> isn't it just mutability with different syntax then? For one thing, in order to take a mutable reference to a binding, that binding must be declared as `mut`. let mut a = 2; let b = 3; let x = &mut a; // let y = &mut b; // error: cannot borrow immutable local variable `b` as mutable