-
Notifications
You must be signed in to change notification settings - Fork 10k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
move_semantics5 makes use of "*", which has not been explained yet #809
Comments
1 I see two mutable refs to Why it works? fn main() {
let mut x = 100;
let y = &mut x;
let z = &mut *y;
// y and z is mutable references to x at the same time, it isn't?
*z = 1000;
*y = 100;
assert_eq!(x, 1200);
} |
@bm0 It does not work though (on purpose):
Playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=7a19b93609ece84708875c8eb375e722 The point of the exercise is making it work by reordering: fn main() {
let mut x = 100;
let y = &mut x;
*y = 100;
let z = &mut *y;
*z = 1000;
assert_eq!(x, 1200);
} Playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=bd6d10a01a666cd7bc6c63ff961e64f4 This is possible because the The borrow checker will refuse compilation if you do use error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable
--> src/main.rs:9:26
|
4 | let y = &mut x;
| ------ mutable borrow occurs here
...
9 | println!("{} {} {}", x, y, z);
| ^ - mutable borrow later used here
| |
| immutable borrow occurs here
error[E0502]: cannot borrow `y` as immutable because it is also borrowed as mutable
--> src/main.rs:9:29
|
6 | let z = &mut *y;
| ------- mutable borrow occurs here
...
9 | println!("{} {} {}", x, y, z);
| ^ - mutable borrow later used here
| |
| immutable borrow occurs here
error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable
--> src/main.rs:8:5
|
4 | let y = &mut x;
| ------ mutable borrow occurs here
...
8 | assert_eq!(x, 1200);
| ^^^^^^^^^^^^^^^^^^^^ immutable borrow occurs here
9 | println!("{} {} {}", x, y, z);
| - mutable borrow later used here
|
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) |
@LeoniePhiline I edited my previous message, now example works. |
@bm0 It works because Here’s what happens if you keep |
@LeoniePhiline it's called freezing, isn't it? |
No, it's called lifetimes. Quote:
Source: https://doc.rust-lang.org/nomicon/lifetimes.html#the-area-covered-by-a-lifetime Read the subchapter "The area covered by a lifetime", and especially check out the example at the bottom, starting with:
This is explaining exactly your scenario. You could say, in your example:
In your example, 'c: {
let z = &mut *y;
// y and z is mutable references to x at the same time, it isn't? <-- No:
// --> `'b`, the lifetime of `y` as mutable borrow of `x`, is "paused" here.
// Because in these lines you only mutate `x` through `z` and not through `y`.
*z = 1000;
} At the end of this block (which does not need lifetime annotations, due to Lifetime Elision), |
@LeoniePhiline thanks a lot! |
@bm0 Very welcome :) |
I think the intent of the original post was lost a bit. I'm a beginner going through the rustlings exercises and I was completely derailed by this exercise because I had no clue what the
It seems backwards to require an understanding of a concept from Chapter 15 to complete an exercise meant to teach the basics of ownership. I found this thread in a google search looking for an explanation for this exercise and the |
I am in exactly the same position as you. Even if the solution doesn't require you to really understand dereferencing to solve it, it's a wholly unnecessary distraction. Especially with the compiler throwing an error on the line with the * operator, you are led to believe you need to know something about how it works in order to fix the error. This is badly written- if it's really supposed to be for beginners. |
I personally found that it nicely makes beginners dive into research to proactively find answers themselves. It’s a great way to discover the rust book and other documentation. If you use the usual rustlings hint (contents at around line 220) you are led to the References and borrowing page. This page provides the solution:
|
That doesn't actually provide the solution, though? The solution is to re-order the existing code. The instructions on that tutorial page, the instructions in the readme, and the hint all provide conflicting information as to what is important about solving that lesson. The lesson isn't one on research or documentation, it's a single lesson in a set of lessons that are all about the concept of passing ownership around a program. Learning to navigate the rust docs is undoubtedly an important skill, but that's clearly not the intent here. |
Fixed in d7024d8 |
This exercise could use a refactor where we don't use the
*
operator. The*
is confusing/distracting at this stage for beginners. Moreover, the readme for the move_semantics section doesn't link to any page explaining what*
does.Couldn't we use String or Vec like in the linked docs instead of playing with dereferencing references to a variable on the stack?
The text was updated successfully, but these errors were encountered: