diff --git a/second-edition/src/ch13-01-closures.md b/second-edition/src/ch13-01-closures.md index 5c8a29cda..9d50c2372 100644 --- a/second-edition/src/ch13-01-closures.md +++ b/second-edition/src/ch13-01-closures.md @@ -33,7 +33,7 @@ number we passed in: use std::thread; use std::time::Duration; -fn simulated_expensive_calculation(intensity: i32) -> i32 { +fn simulated_expensive_calculation(intensity: u32) -> u32 { println!("calculating slowly..."); thread::sleep(Duration::from_secs(2)); intensity @@ -72,7 +72,7 @@ fn main() { simulated_random_number ); } -# fn generate_workout(intensity: i32, random_number: i32) {} +# fn generate_workout(intensity: u32, random_number: u32) {} ``` Listing 13-2: A `main` function with hardcoded values to @@ -96,13 +96,13 @@ will be made to this function: # use std::thread; # use std::time::Duration; # -# fn simulated_expensive_calculation(num: i32) -> i32 { +# fn simulated_expensive_calculation(num: u32) -> u32 { # println!("calculating slowly..."); # thread::sleep(Duration::from_secs(2)); # num # } # -fn generate_workout(intensity: i32, random_number: i32) { +fn generate_workout(intensity: u32, random_number: u32) { if intensity < 25 { println!( "Today, do {} pushups!", @@ -166,13 +166,13 @@ variable, as shown in Listing 13-4: # use std::thread; # use std::time::Duration; # -# fn simulated_expensive_calculation(num: i32) -> i32 { +# fn simulated_expensive_calculation(num: u32) -> u32 { # println!("calculating slowly..."); # thread::sleep(Duration::from_secs(2)); # num # } # -fn generate_workout(intensity: i32, random_number: i32) { +fn generate_workout(intensity: u32, random_number: u32) { let expensive_result = simulated_expensive_calculation(intensity); @@ -268,7 +268,7 @@ argument values we want to use, as shown in Listing 13-6: # use std::thread; # use std::time::Duration; # -fn generate_workout(intensity: i32, random_number: i32) { +fn generate_workout(intensity: u32, random_number: u32) { let expensive_closure = |num| { println!("calculating slowly..."); thread::sleep(Duration::from_secs(2)); @@ -345,7 +345,7 @@ would look like the definition shown in Listing 13-7: # use std::thread; # use std::time::Duration; # -let expensive_closure = |num: i32| -> i32 { +let expensive_closure = |num: u32| -> u32 { println!("calculating slowly..."); thread::sleep(Duration::from_secs(2)); num @@ -363,8 +363,8 @@ closure syntax is similar to function syntax, except for the use of pipes and the amount of syntax that is optional: ```rust,ignore -fn add_one_v1 (x: i32) -> i32 { x + 1 } -let add_one_v2 = |x: i32| -> i32 { x + 1 }; +fn add_one_v1 (x: u32) -> u32 { x + 1 } +let add_one_v2 = |x: u32| -> u32 { x + 1 }; let add_one_v3 = |x| { x + 1 }; let add_one_v4 = |x| x + 1 ; ``` @@ -383,7 +383,7 @@ parameter. This closure isn’t very useful except for the purposes of this example. Note that we haven’t added any type annotations to the definition: if we then try to call the closure twice, using a `String` as an argument the first time and an -`i32` the second time, we’ll get an error: +`u32` the second time, we’ll get an error: Filename: src/main.rs @@ -447,8 +447,8 @@ example, we can use the `Fn` trait. We add types to the `Fn` trait bound to represent the types of the parameters and return values the closures must have in order to match this trait bound. In -this case, our closure has a parameter of type `i32` and returns an `i32`, so -the trait bound we specify is `Fn(i32) -> i32`. +this case, our closure has a parameter of type `u32` and returns an `u32`, so +the trait bound we specify is `Fn(u32) -> u32`. Listing 13-9 shows the definition of the `Cacher` struct that holds a closure and an optional result value: @@ -457,10 +457,10 @@ and an optional result value: ```rust struct Cacher - where T: Fn(i32) -> i32 + where T: Fn(u32) -> u32 { calculation: T, - value: Option, + value: Option, } ``` @@ -469,16 +469,16 @@ closure in `calculation` and an optional result in `value` The `Cacher` struct has a `calculation` field of the generic type `T`. The trait bounds on `T` specify that it’s a closure by using the `Fn` trait. Any -closure we want to store in the `calculation` field must have one `i32` +closure we want to store in the `calculation` field must have one `u32` parameter (specified within the parentheses after `Fn`) and must return an -`i32` (specified after the `->`). +`u32` (specified after the `->`). > Note: Functions implement all three of the `Fn` traits too. If what we want to > do doesn’t require capturing a value from the environment, we can use a > function rather than a closure where we need something that implements an `Fn` > trait. -The `value` field is of type `Option`. Before we execute the closure, +The `value` field is of type `Option`. Before we execute the closure, `value` will be `None`. When code using a `Cacher` asks for the *result* of the closure, the `Cacher` will execute the closure at that time and store the result within a `Some` variant in the `value` field. Then if the code asks for @@ -492,14 +492,14 @@ The logic around the `value` field we’ve just described is defined in Listing ```rust # struct Cacher -# where T: Fn(i32) -> i32 +# where T: Fn(u32) -> u32 # { # calculation: T, -# value: Option, +# value: Option, # } # impl Cacher - where T: Fn(i32) -> i32 + where T: Fn(u32) -> u32 { fn new(calculation: T) -> Cacher { Cacher { @@ -508,7 +508,7 @@ impl Cacher } } - fn value(&mut self, arg: i32) -> i32 { + fn value(&mut self, arg: u32) -> u32 { match self.value { Some(v) => v, None => { @@ -552,14 +552,14 @@ Listing 13-11 shows how we can use this `Cacher` struct in the # use std::time::Duration; # # struct Cacher -# where T: Fn(i32) -> i32 +# where T: Fn(u32) -> u32 # { # calculation: T, -# value: Option, +# value: Option, # } # # impl Cacher -# where T: Fn(i32) -> i32 +# where T: Fn(u32) -> u32 # { # fn new(calculation: T) -> Cacher { # Cacher { @@ -568,7 +568,7 @@ Listing 13-11 shows how we can use this `Cacher` struct in the # } # } # -# fn value(&mut self, arg: i32) -> i32 { +# fn value(&mut self, arg: u32) -> u32 { # match self.value { # Some(v) => v, # None => { @@ -580,7 +580,7 @@ Listing 13-11 shows how we can use this `Cacher` struct in the # } # } # -fn generate_workout(intensity: i32, random_number: i32) { +fn generate_workout(intensity: u32, random_number: u32) { let mut expensive_result = Cacher::new(|num| { println!("calculating slowly..."); thread::sleep(Duration::from_secs(2)); @@ -675,7 +675,7 @@ if it’s present. If it’s not present, the `Cacher` will call the closure and save the resulting value in the hash map associated with its `arg` value. Another problem with the current `Cacher` implementation is that it only -accepts closures that take one parameter of type `i32` and return an `i32`. We +accepts closures that take one parameter of type `u32` and return an `u32`. We might want to cache the results of closures that take a string slice and return `usize` values, for example. To fix this issue, try introducing more generic parameters to increase the flexibility of the `Cacher` functionality. diff --git a/second-edition/src/ch13-02-iterators.md b/second-edition/src/ch13-02-iterators.md index e91e6829e..f41a69536 100644 --- a/second-edition/src/ch13-02-iterators.md +++ b/second-edition/src/ch13-02-iterators.md @@ -242,11 +242,11 @@ struct instances. It will return only shoes that are the specified size: ```rust,test_harness #[derive(PartialEq, Debug)] struct Shoe { - size: i32, + size: u32, style: String, } -fn shoes_in_my_size(shoes: Vec, shoe_size: i32) -> Vec { +fn shoes_in_my_size(shoes: Vec, shoe_size: u32) -> Vec { shoes.into_iter() .filter(|s| s.size == shoe_size) .collect()