Ch. 9: correctly demonstrate privacy with module

The code as actually written *did* conform to the expetaction of the
text, but only because it was in a `lib.rs` file and so in a module
distinct from the scope directly accessible from `main.rs`; as shown in
the text presentation, however, it was not obvious that it was in a
`lib.rs`, and that detail was elided.

Rename the `lib.rs` to `guessing_game.rs` and declare it as a module in
the `main.rs` file, update the `Listing` to name it, and update the text
to call out the creation of the module.
This commit is contained in:
Chris Krycho
2025-03-17 17:12:12 -06:00
parent 6156ff18b2
commit a6bede67a2
3 changed files with 16 additions and 13 deletions

View File

@@ -3,6 +3,8 @@ use rand::Rng;
use std::cmp::Ordering;
use std::io;
mod guessing_game;
fn main() {
println!("Guess the number!");

View File

@@ -159,23 +159,24 @@ program only operated on values between 1 and 100, and it had many functions
with this requirement, having a check like this in every function would be
tedious (and might impact performance).
Instead, we can make a new type and put the validations in a function to create
an instance of the type rather than repeating the validations everywhere. That
way, its safe for functions to use the new type in their signatures and
confidently use the values they receive. Listing 9-13 shows one way to define a
`Guess` type that will only create an instance of `Guess` if the `new` function
receives a value between 1 and 100.
Instead, we can make a new type in a dedicated module and put the validations in
a function to create an instance of the type rather than repeating the
validations everywhere. That way, its safe for functions to use the new type in
their signatures and confidently use the values they receive. Listing 9-13 shows
one way to define a `Guess` type that will only create an instance of `Guess` if
the `new` function receives a value between 1 and 100.
<Listing number="9-13" caption="A `Guess` type that will only continue with values between 1 and 100">
<Listing number="9-13" caption="A `Guess` type that will only continue with values between 1 and 100" file-name="src/guessing_game.rs">
```rust
{{#rustdoc_include ../listings/ch09-error-handling/listing-09-13/src/lib.rs}}
{{#rustdoc_include ../listings/ch09-error-handling/listing-09-13/src/guessing_game.rs}}
```
</Listing>
First we define a struct named `Guess` that has a field named `value` that
holds an `i32`. This is where the number will be stored.
First we create a new module named `guessing_game`. Next we define a struct in
that module named `Guess` that has a field named `value` that holds an `i32`.
This is where the number will be stored.
Then we implement an associated function named `new` on `Guess` that creates
instances of `Guess` values. The `new` function is defined to have one
@@ -197,9 +198,9 @@ a _getter_ because its purpose is to get some data from its fields and return
it. This public method is necessary because the `value` field of the `Guess`
struct is private. Its important that the `value` field be private so code
using the `Guess` struct is not allowed to set `value` directly: code outside
the module _must_ use the `Guess::new` function to create an instance of
`Guess`, thereby ensuring theres no way for a `Guess` to have a `value` that
hasnt been checked by the conditions in the `Guess::new` function.
the `guessing_game` module _must_ use the `Guess::new` function to create an
instance of `Guess`, thereby ensuring theres no way for a `Guess` to have a
`value` that hasnt been checked by the conditions in the `Guess::new` function.
A function that has a parameter or returns only numbers between 1 and 100 could
then declare in its signature that it takes or returns a `Guess` rather than an