-
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
hint (or directions?) for move_semantics2 are confusing/wrong? #1596
Comments
I'm currently doing this and get extemely confused too. 😕 |
The current version of the exercise tries to teach both the concept of moving values as well as how to use references. I think the goal of the exercise is unclear because it is trying to teach too much within a single exercise. As @solarshado points out, the difference in behavior is unfortunate. Could the exercise be split into two? One exercise could teach how to pass ownership, such as in listing 4-4. While the other could teach how to pass arguments as references to functions such as in chapter 4.2 of the book. |
Adding another confused voice to this. Hint 1 - "Make another, separate version of the data that's in This one needs a rethink. Too much going on, needs to focus on the concept of moving more. |
Hello, First time rust writer, long time programmer. I thought I'd add add some code references for context, as I also found myself to be a little lost with this problem as-well. For reference, here is the original problem rustlings/exercises/move_semantics/move_semantics2.rs Lines 1 to 32 in 464cb55
Here are the hints associated: Lines 294 to 314 in 464cb55
If I understand the problem correctly, the author wants the reader to consider how the problem could be solved with and without changing the signature of the original For 1: Point 1 says to "Make another, separate version of the data that's in // Possibility 1: two disconnected variables (I think this is what the author intended?)
fn main() {
let vec0 = fill_vec(Vec::new());
let mut vec1 = fill_vec(Vec::new()); // the rest of the file remains unchanged
}
// Possibility 2: slicing
// This doesn't fit - `vec0` shadows itself and depends on `vec1` for it's values. I believe
// `fill_vec` is intended to be the only function adding to the `vec0`
fn main() {
let vec0 = Vec::new();
let mut vec1 = fill_vec(Vec::new());
let vec0 = &[0..3]; // the rest of the file remains unchanged
} Whatever the authors intended solution was, I do think clarity in the first hint would be beneficial. Hint 2: It seems to suggest taking a non-mutable reference into Hint 3: This hint seems to be identical to what I hope I made the confusion I (and maybe the others) was having more clear. I'll finish on a note that this repo is directed towards new developers, so I'm sure all of us using it to learn would appreciate an experienced dev chiming in here. |
I actually think the best solution is to just return ownership of the vector. The task can be simplified by only having a single variable as shown below: fn main(){
let mut vec0 = Vec::new();
vec0 = fill_vec(vec0);
//...
} The starting point could have a call to fill_vec without capturing the return value, which would trigger the appropriate compiler error. fn main(){
let mut vec0 = Vec::new();
fill_vec(vec0);
//...
} I can submit a PR with these changes. More work might be needed to ensure the exercises flow nicely together. |
@JoachimT99 Yeah.. that looks much better! |
Closing this cautiously because #1660 got merged. Do let me know if those exercises are still too difficult/unintelligble! |
For what it's worth... the part I found extremely confusing was that I needed to modify the test/calling-code, not just the function. I do think better hints would help. |
Should we be modifying the test? |
My solution to this for the first hint was to do: let vec1 = fill_vec(vec0.clone()); and trying to do the second hint which I'm SUPER confused by: fn main() {
let vec0 = vec![22, 44, 66];
let vec1 = fill_vec(&vec0);
assert_eq!(vec0, vec![22, 44, 66]);
assert_eq!(vec1, vec![22, 44, 66, 88]);
}
fn fill_vec(vec: &Vec<i32>) -> Vec<i32> {
let mut vec = vec;
let mut vec = vec.to_vec();
vec.push(88);
vec
} which... I don't know if it's right or what it's supposed to be... but it works. honestly the errors that i got from the compiler while trying to do the second one were super confusing because they kept telling me to change function signature stuff, and then once I did it kept complaining about types differing in mutability originally: fn fill_vec(vec: &Vec<i32>) -> Vec<i32> {
let mut vec:&mut Vec<i32> = vec;
vec.push(88);
vec.to_vec()
} So yeah. just thought I'd let you know my experience with this bc this is the first exercise I've found to be confusing. That said, rustlings rules. Great way to learn. 10/10 so far |
Working my way through 5.5.1, and the hint for
move_semantics2
suggests multiple solutions. However, unless I've misunderstood something, neither of the first two suggestions produce the "expected output" described in the comments abovemain()
; they both copyvec0
before it's populated, leaving it empty when printed.As far as I can tell, the only suggestion that does work is the third (mutably borrow a reference to
vec0
), which, contradictory to what the hint says, is the only option which doesn't affect the output of the firstprintln!
.The text was updated successfully, but these errors were encountered: