ELI5/Newbie Questions


#1

Hello Rustaceans,

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.

Here is my source

Questions:

  1. 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();

  2. 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() {
  1. 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?

#2
  1. The flush method comes from the Write trait, which is not imported by default. You need to import a trait to use its methods.
  2. 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.
  3. 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 String derefs 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).


#3

Thank you for the reply @krdln

  • 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.


#4

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.


#5

I don’t have time to answer your questions right now, but I wrote a simple text game for a Ludum Dare a while back, you might find it interesting https://github.com/steveklabnik/ludum