Hi All! Welcome to the Reading Club for Rust’s “The Book” (“The Rust Programming Language”). This is week 1 (the beginning!!).
Have a shot at going through “the reading” and post any thoughts, confusions or insights here
“The Reading”
-
Finish up to Chapter 2: “Programming a Guessing Game”
-
The Book: https://rust-book.cs.brown.edu/title-page.html (the special Brown University version with quizzes etc)
The Twitch Stream
- @sorrybookbroke@sh.itjust.works ran a twitch stream on these chapters which is now on YouTube: https://www.youtube.com/watch?v=ou2c5J6FmsM
- You might prefer watching and listening to that rather than reading the book.
- Be sure to catch future streams (will/should be weekly: https://www.twitch.tv/deerfromsmoke)
What’s Next Week?
- Chapters 3 and 4
- Start thinking about challenges or puzzles to try as we go in order to get some applied practice!
- EG, Advent of Code
- Maybe some basic/toy web apps such as a “todo”
Thanks!
Seems I gotta dig into the borrow checker before thinking too much about this!
Otherwise, compiling your code snippet is a nice illustration of how helpful the compiler tries to be … lots of tips in the output there! To anyone else, just try running
rustc
on this, with the secondprintln!
uncommented and see the output, which is half error half linting.Yea. So if the second
println!
were uncommented, how could we compile this? From what you’ve said, I’d guess that&
means “borrow” (ie, not “move” ownership).So if we alter
abc
to take a&String
type and notString
, and therefore only “borrow” the variable, and then pass in&v
and notv
to pass in a “borrowed” variable, it should compile.fn abc(v: &String) { println!("v is {}", v); } fn main() { let mut v=String::from("ab"); v.push('c'); abc(&v); println!("v is {}", v); }
It seems to!
Of course, as the compiler suggests, we could instead just pass in
v.clone()
which presumably creates a new variable and effectively “passes by value”.Digging in a bit more, what happens if
abc
(tries to) mutate the variable?We can add
v.push('X')
toabc
and see if we get different printouts. As the compiler would tell us, we would need to make the argumentv
mutable for this to work.fn abc(mut v: String) { v.push('X'); println!("v is {}", v); } fn main() { let mut v=String::from("ab"); v.push('c'); abc(v.clone()); println!("v is {}", v); } // OUTPUT: // v is abcX // v is abc
I’m not clear on why I don’t have to declare that the
v.clone()
is mutable in anyway though.What about trying the same with a "borrowed’ variable?
Well we need mutable borrowed variables, so necessary adjustments to the types of
abc
and its call inmain
. And adding an additional mutation ofv
inmain
afterabc
is called, and we get two different println outputs, with each mutation applying to the same variable.fn abc(v: &mut String) { v.push('X'); println!("v is {}", v); } fn main() { let mut v=String::from("ab"); v.push('c'); abc(&mut v); v.push('Y'); println!("v is {}", v); } // OUTPUT // v is abcX // v is abcXY
It’s covered in detail in chapter 4.