Skip to content
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

Guessing Game rand example doesn't compile #1663

Closed
zvory opened this issue Dec 7, 2018 · 21 comments
Closed

Guessing Game rand example doesn't compile #1663

zvory opened this issue Dec 7, 2018 · 21 comments

Comments

@zvory
Copy link

zvory commented Dec 7, 2018

Versions

Book:

rustc: rustc 1.31.0 (abe02cefd 2018-12-04)

cargo: cargo 1.31.0 (339d9f9c8 2018-11-16)

What is the issue:

When going through the Guessing Game tutorial:

Listing 2-3 contains some code that should use rand:

use std::io;
use rand::Rng;

fn main() {
    println!("Guess the number!");

    let secret_number = rand::thread_rng().gen_range(1, 101);

    println!("The secret number is: {}", secret_number);

    println!("Please input your guess.");

    let mut guess = String::new();

    io::stdin().read_line(&mut guess)
        .expect("Failed to read line");

    println!("You guessed: {}", guess);
}

This code does not compile, with the following errors:

azvorygi@bit-shifter:~/Code/rst$ cargo run
   Compiling rst v0.1.0 (/users/azvorygi/Code/rst)                                                                                                                                            
error[E0432]: unresolved import `rand`                                                                                                                                                        
 --> src/main.rs:2:5                                                                                                                                                                          
  |                                                                                                                                                                                           
2 | use rand::Rng;                                                                                                                                                                            
  |     ^^^^ maybe a missing `extern crate rand;`?                                                                                                                                            
                                                                                                                                                                                              
warning: unused import: `rand::Rng`                                                                                                                                                           
 --> src/main.rs:2:5                                                                                                                                                                          
  |                                                                                                                                                                                           
2 | use rand::Rng;                                                                                                                                                                            
  |     ^^^^^^^^^                                                                                                                                                                             
  |                                                                                                                                                                                           
  = note: #[warn(unused_imports)] on by default                                                                                                                                               
                                                                                                                                                                                              
error[E0599]: no method named `gen_range` found for type `rand::ThreadRng` in the current scope                                                                                               
 --> src/main.rs:7:44                                                                                                                                                                         
  |                                                                                                                                                                                           
7 |     let secret_number = rand::thread_rng().gen_range(1, 101);                                                                                                                             
  |                                            ^^^^^^^^^                                                                                                                                      
  |                                                                                                                                                                                           
  = help: items from traits can only be used if the trait is in scope                                                                                                                         
help: the following trait is implemented but not in scope, perhaps add a `use` for it:                                                                                                        
  |                                                                                                                                                                                           
1 | use rand::Rng;                                                                                                                                                                            
  |                                                                                                                                                                                           
                                                                                                                                                                                              
error: aborting due to 2 previous errors                                                                                                                                                      
                                                                                                                                                                                              
Some errors occurred: E0432, E0599.                                                                                                                                                           
For more information about an error, try `rustc --explain E0432`.                                                                                                                             
error: Could not compile `rst`.                                                                                                                                                               

This is of course after adding the following to my Cargo.toml:

[dependencies]
rand = "0.3.14"

Here's a github repo with my repo when it is breaking: https://github.com/zvory/guessing-game-breaking

@carols10cents
Copy link
Member

Hi, your Cargo.toml also needs to have edition="2018" in it. If you ran cargo new with Rust 1.31.0, your Cargo.toml should have this in it automatically. If you created the project with a version of Rust earlier than 1.31, you need to opt in to the edition by adding edition="2018" to your Cargo.toml manually.

When I build this code with edition="2018" in Cargo.toml, it completes successfully.

I see that the Cargo.toml shown at the beginning of Chapter 2 doesn't have the edition metadata, so perhaps that caused you to remove it? That's the only bug I can see here; I'm going to fix that.

Please let me know if anything else regarding the edition key was confusing.

@carols10cents
Copy link
Member

BTW thank you for providing a repo, that made it very easy to check what the problem was!

@zvory
Copy link
Author

zvory commented Dec 7, 2018

😊 the "thanks for providing a repo" thing was very validating and nice, thanks! also thanks for taking care of this issue, <3 !

@adamkpickering
Copy link

I found a related inconsistency. Right below the example code that @zvory quoted (listing 2-3), the first paragraph says:

First, we add a line that lets Rust know we’ll be using the rand crate as an external dependency. This also does the equivalent of calling use rand, so now we can call anything in the rand crate by placing rand:: before it.

It appears that this is referring to a extern crate rand; line at the top of the file. However, this line is not in the example code!

As a sidenote, it would make sense to add a note in section 1.1 that explains that the book is assuming that the reader is using 1.31.0 or later. In my case, I did not use the rustup tool, and instead used sudo apt install rustc, which on Ubuntu 16.04 installed 1.30.0.

Thanks for your work on the book!

@carols10cents
Copy link
Member

I found a related inconsistency. Right below the example code that @zvory quoted (listing 2-3), the first paragraph says:

First, we add a line that lets Rust know we’ll be using the rand crate as an external dependency. This also does the equivalent of calling use rand, so now we can call anything in the rand crate by placing rand:: before it.

It appears that this is referring to a extern crate rand; line at the top of the file. However, this line is not in the example code!

Yep! That has been fixed in master, but we haven't pulled the fix into rust-lang/rust to update doc.rust-lang.org/book yet. It'll be there soon!

As a sidenote, it would make sense to add a note in section 1.1 that explains that the book is assuming that the reader is using 1.31.0 or later. In my case, I did not use the rustup tool, and instead used sudo apt install rustc, which on Ubuntu 16.04 installed 1.30.0.

Yup! We plan to add that; we're just deciding exactly where it should go in both online and print. It's tracked as an item in the "Smaller changes" section of this issue.

Thanks for your work on the book!

You're welcome, thank you for your comments! ❤️

@apghero
Copy link

apghero commented Feb 28, 2019

Hi @carols10cents -- just wanted to bump this, as I came here to open an issue for the extern crate rand stuff adam mentioned. There's a legitimate reason that it hasn't been pushed to the web yet, but it's been more than 2 months since it was fixed, and the old text is still confusing to readers.

@steveklabnik
Copy link
Member

There's nothing to do; it will make its way to stable like everything else. It can take up to 12 weeks, and since I think we may have missed one update, 18 weeks, for things to percolate up. That's just the way things work, unfortunately.

@apghero
Copy link

apghero commented Feb 28, 2019

Thanks, @steveklabnik, for the explanation.

That's just the way things work, unfortunately.

I can think of legitimate reasons that it works this way (I'm new here, btw), but if it's "unfortunate" that it works this way, is it worth reconsidering? Perhaps this isn't the change to die on a hill for, though...

@steveklabnik
Copy link
Member

Well, there's pros and cons, like everything else. The pros far outweigh the cons. This might make for a good thread on users.rust-lang.org though!

@abelardolg
Copy link

abelardolg commented Apr 12, 2019

Hi there,
I''d like to give you to know a compilation error while I modified this game.
Exactly, I added these lines:

let guess: u32 = guess.trim().parse() {
            Ok(num) => num,
            Err(_) => continue,
        };

It showed the following message:
src/main.rs:17:46

|
17 | let guess: u32 = guess.trim().parse() {
| ^ expected one of ., ;, ?, or an operator here

The "^" near "expected" (at the message) points out to opening curly bracket close to "parse()".

Compiling it with the last version of Rust compiler.
Regards.

@steveklabnik
Copy link
Member

You're missing a match after the =

@abelardolg
Copy link

abelardolg commented Apr 12, 2019

:O
How could I miss that keyword????!!!!

Sorry for the inconveniences.

Best regards..and thanks, @steveklabnik

@DadouBordeaux
Copy link

DadouBordeaux commented May 19, 2019

For those who where already stuck with this problem even after adding edition="2018" in cargo.toml :
Don't forget to run rustup update ...

About the book, what to do think about adding a line to explain that use rand::Rng; is only availlable in a specific version of Rust ?

edit : I just went to see that the first page of the book states : This version of the text assumes you are using Rust 1.31.0 or later.

@russellyoung
Copy link

russellyoung commented Feb 1, 2020

I still have the same problem in Feb 2020, running 1.41.0. Going through the tutorial I needed to google and find this. Adding

extern crate rand;
use crate::rand::Rng;

fixed the issue, but it would be nice to have the tutorial work, it's been over a year.

edit: same deal for the next example, requires use std::cmp::Ordering; be added. I assume all sample code will have the same problem.

@carols10cents
Copy link
Member

@russellyoung do you have edition = "2018" in your Cargo.toml?

@russellyoung
Copy link

@carols10cents Thanks for checking in on this. Yes, the version I have (1.41.0) included that in Cargo.toml, and I confirmed that it was there before posting.

@carols10cents
Copy link
Member

@russellyoung I am able to build the code in this directory with Rust 1.41.0, and it doesn't have the extern crate lines you mentioned.

Can you post the exact error you got before adding those lines, and the complete code you ran with that error? I would like to fix this problem, but I don't understand the problem completely yet.

@russellyoung
Copy link

@carols10cents Sure, here it is.

toml:

[package]
name = "guessing"
version = "0.1.0"
authors = ["russell <russ@XXX.com>"]
edition = "2018"

[dependencies]
rand = "0.5.5"

code:


use std::io;
//use crate::rand::Rng;

fn main() {
    println!("Guess the number!");

    let secret_number = rand::thread_rng().gen_range(1, 101);

    println!("The secret number is: {}", secret_number);
    loop {
        println!("Please input your guess.");
        
        let mut guess = String::new();
        
        io::stdin().read_line(&mut guess)
            .expect("aa");

        let guess: u32 = match guess.trim().parse() {
            Ok(num) => num,
            Err(x) => {
                println!("{}", x);
                continue;
            }
        };
        
        println!("You guessed: {}", guess);
    }
}

With the use statement included it runs correctly. With it commented out as in the included code it gets the following error:

$ cargo run
   Compiling guessing v0.1.0 (/Users/russell/personal/projects/rust/guessing)
error[E0599]: no method named `gen_range` found for type `rand::ThreadRng` in the current scope
 --> src/main.rs:9:44
  |
9 |     let secret_number = rand::thread_rng().gen_range(1, 101);
  |                                            ^^^^^^^^^ method not found in `rand::ThreadRng`
  |
  = help: items from traits can only be used if the trait is in scope
help: the following trait is implemented but not in scope; perhaps add a `use` for it:
  |
3 | use crate::rand::Rng;
  |

error: aborting due to previous error

For more information about this error, try `rustc --explain E0599`.
error: could not compile `guessing`.

To learn more, run the command again with --verbose.

As a rust rookie I would guess the use statement should not be necessary, but maybe it is just the tutorial sample code that needs changing.

@carols10cents
Copy link
Member

@russellyoung you do need a use statement, as shown in the generating a random number section, Listing 2-3 adds use rand::Rng; and under the listing the text reads "First, we add a use line: use rand::Rng. The Rng trait defines methods that random number generators implement, and this trait must be in scope for us to use those methods. Chapter 10 will cover traits in detail."

@russellyoung
Copy link

oh my goodness is my face red, I guess I was going through too fast and just missed those "unimportant" lines. Sorry to have taken your time. And I'm sorry my postings have an identifiable name :-|

@carols10cents
Copy link
Member

It happens. Thank you for the apology, take care!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants