4 ms·
>I literally don't remember any unpleasant surprises of this form when learning Rust I can't say I find Rust's pattern matching rules particularly pleasant. Th
by fauigerzigerk 3y ago
>I literally don't remember any unpleasant surprises of this form when learning Rust
I can't say I find Rust's pattern matching rules particularly pleasant. The rules are convoluted and arbitrary
https://doc.rust-lang.org/stable/reference/patterns.html https://doc.rust-lang.org/stable/reference/patterns.html
Also, it has often been surprising to me how code that looks like it's entirely read-only will try to move stuff.
E.g, this works:
let numbers = [1, 2, 3];
for n in numbers {
println!("{}", n);
}
for n in numbers {
println!("{}", n);
}
This doesn't work:
let numbers2 = vec![1, 2, 3];
for n in numbers2 {
println!("{}", n);
}
for n in numbers2 {
println!("{}", n);
}
I understand why that is and I know how to fix it, but I don't like it. There is a long list of things in Rust that I find understandable but also unpleasant. In that sense it really is a worthy successor to C++. Smart people making unpleasant decisions for good reasons.
- tialaramex 3y agoI think your mental model is wrong if you thought a consuming operation like IntoIterator::into_iter is read only. The reason the first one works is that [T; N] is Copy if T is Copy, and i32 is Copy so therefore [i32; 3] is Copy. So it's actually consuming two arrays, each of those for loops consumes the array to make an iterator, but since it's Copy it just leaves a perfectly good copy of the array behind in the variable. The compiler can see what we're doing here and won't pointlessly duplicate the array (presumably) but that's conceptually what's happening. The second one doesn't work because the Vec<i32> isn't Copy, so, we consume it and now it's gone, when we reach the second for loop the variable numbers2 is gone already.
- fauigerzigerk 3y agoAs I said, I understand what's going on here. I just don't like it.
- eddd-ddde 3y agoBeing read only and move semantics are orthogonal, you can read and write with or without moving. So you shouldn't make assumptions whether something will be moved or not based on read only preconditions.
- fauigerzigerk 3y agoMoving out of a variable changes it's state. That's not read-only.
- eddd-ddde 3y agoThere is a difference between a variable and a value. The value is definitely read only or you would need a mut modifier. The variable binding changes in a similar way to shadowing it with a new 'let' on the same name.
- fauigerzigerk 3y agoThis would imply that the variable can get its value back once the new binding is out of scope. But that is not the case as this doesn't compile: let s1 = String::from("abc"); { let s2 = s1; } println!("{}", s1); //borrow of moved value: `s1` But I do understand what you're getting at. In a sense, a move is not a runtime concept at all. The compiler simply considers the variable as no longer readable unless and until a new value is actually written to it.