book
book copied to clipboard
Example listing-09-13 works even using Guess { value: guess } instead Guess::new(guess)
- I have searched open and closed issues and pull requests for duplicates, using these search terms:
- listing-09-13
- listing 09-13
- 9-13
- I have checked the latest
mainbranch to see if this has already been fixed, in this file:- Yes
URL to the section(s) of the book with this problem: https://doc.rust-lang.org/book/ch09-03-to-panic-or-not-to-panic.html https://github.com/rust-lang/book/blob/main/listings/ch09-error-handling/listing-09-13/src/main.rs Description of the problem: The text under the example says:
This public method is necessary because the value field of the
Guessstruct is private. It’s important that the value field be private so code using theGuessstruct is not allowed to set value directly: code outside the module must use theGuess::newfunction to create an instance ofGuess, thereby ensuring there’s no way for aGuessto have a value that hasn’t been checked by the conditions in theGuess::newfunction.
But if you call Guess { value: guess } instead Guess::new(guess) it works without errors.
Suggested fix:
use rand::Rng;
use std::cmp::Ordering;
use std::io;
use crate::guess_module::Guess;
// ANCHOR: here
pub mod guess_module {
pub struct Guess {
value: i32,
}
impl Guess {
pub fn new(value: i32) -> Guess {
if value < 1 || value > 100 {
panic!("Guess value must be between 1 and 100, got {}.", value);
}
Guess { value }
}
pub fn value(&self) -> i32 {
self.value
}
}
}
// ANCHOR_END: here
fn main() {
println!("Guess the number!");
let secret_number = rand::thread_rng().gen_range(1..=100);
loop {
println!("Please input your guess.");
let mut guess = String::new();
io::stdin()
.read_line(&mut guess)
.expect("Failed to read line");
let guess: i32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => continue,
};
// This way to create a guess will work
let guess = Guess::new(guess);
// If you uncomment the next line instead the previous one we will have an error
// let guess = Guess { value: guess };
match guess.value().cmp(&secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => {
println!("You win!");
break;
}
}
}
}
Hi @tomaslucas, thanks for the issue! You're correct: we are not actually wrapping that in a module so it is not private. I've flagged this up for us to tackle in working on the 2024 revision.