I'm new to Rust and programming in general pretty much. I've taken the guessing game tutorial from the Rust Book and have started modifying it to try and create a simple text game, but to my dismay I haven't gotten very far without a good amount of questions popping up.
Why doesn't use std::io::stdout work as a use for the below code, and per the docs I don't understand why I have to use use std::io::{self, Write} to use the following code?
io::stdout().flush().unwrap();
Based on the docs, trim removes any whitespaces in the string. This, I'm sure is helpful to get matching correctly - however, why is it required for this to compile?
What would I use if I wanted to match but preserve whitespace, such as the sentence "I like turtles"?
match player_command.trim() {
Per the guessing game, the code used to do matching on the numbers uses match guess.cmp(&secret_number) - Why do you need to pass a reference as your argument when using cmp if it's not modifying the variable, but for match player_command.trim() I can pass the variable, and don't have to pass &player_command?
The flush method comes from the Write trait, which is not imported by default. You need to import a trait to use its methods.
The player_command is a String, while you're matching on &str. The trim is just one of many methods that goes from String to &str. You can just call as_ref() instead of trim(). &*player_command and &player_command[..] would also get you a &str.
Oh, and trim() doesn't remove whitespace from inside of the string. What's even more interesting, it can't! That's because the &str is only a borrow, so the actual string has to exist somewhere else – in this case, it's the part of the original string.
Method calls do auto-referencing (auto-dereferencing too). So the trim is defined on &self (so &String, not String) and Rust automatically does (&player_command).trim(). Actually, this case is even slightly more complicated, as the trim() is defined on &str, which Stringderefs to so Rust actually performs a coercion from &String to &str before calling the method.
If you're confused by two types of strings, you can think of String as the string builder or string buffer, while &str is just a string view (of any string).
I added use std::io::stdout and use std::io::Write to my original code and it compiles correctly now using the explicit use.
I see now in the docs that matches only takes &str and not String - I guess I didn't understand that there was a difference. So by me using .trim() it auto-converted my player_command String type to a &str type and that's how it was able to match if I got that correctly?
I'm still unsure what the differences are between String and &str, but it looks as though I need to study Ownership and Strings in the docs a bit more and play around with it this weekend.
Thank you again - that cleared up a majority of what I was having problems with I believe.
Yeah, that's why that made it compile. There are two conversions going on here actually – first the compiler converts String → &str, so it can call trim, and the trim itself trims a &str into another &str.
I'm pretty sure that it'll get clearer after reading the book! Also, check out the Ownership chapter from the next iteration of The Book. Some say it's a lot cleaner than the current one.