|
3 | 3 | The `newtype` idiom gives compile time guarantees that the right type of value is supplied |
4 | 4 | to a program. |
5 | 5 |
|
6 | | -For example, an age verification function that checks age in years, *must* be given |
7 | | -a value of type `Years`. |
| 6 | +For example, a function that measures distance in miles, *must* be given |
| 7 | +a value of type `Miles`. |
8 | 8 |
|
9 | 9 | ```rust, editable |
10 | | -struct Years(i64); |
| 10 | +struct Miles(f64); |
11 | 11 |
|
12 | | -struct Days(i64); |
| 12 | +struct Kilometers(f64); |
13 | 13 |
|
14 | | -impl Years { |
15 | | - pub fn to_days(&self) -> Days { |
16 | | - Days(self.0 * 365) |
| 14 | +impl Miles { |
| 15 | + pub fn to_kilometers(&self) -> Kilometers { |
| 16 | + Kilometers(self.0 * 1.609344) |
17 | 17 | } |
18 | 18 | } |
19 | 19 |
|
20 | | -impl Days { |
21 | | - /// truncates partial years |
22 | | - pub fn to_years(&self) -> Years { |
23 | | - Years(self.0 / 365) |
| 20 | +impl Kilometers { |
| 21 | + pub fn to_miles(&self) -> Miles { |
| 22 | + Miles(self.0 / 1.609344) |
24 | 23 | } |
25 | 24 | } |
26 | 25 |
|
27 | | -fn is_adult(age: &Years) -> bool { |
28 | | - age.0 >= 18 |
| 26 | +fn is_a_marathon(distance: &Miles) -> bool { |
| 27 | + distance.0 >= 26.2 |
29 | 28 | } |
30 | 29 |
|
31 | 30 | fn main() { |
32 | | - let age = Years(25); |
33 | | - let age_days = age.to_days(); |
34 | | - println!("Is an adult? {}", is_adult(&age)); |
35 | | - println!("Is an adult? {}", is_adult(&age_days.to_years())); |
36 | | - // println!("Is an adult? {}", is_adult(&age_days)); |
| 31 | + let distance = Miles(30.0); |
| 32 | + let distance_km = distance.to_kilometers(); |
| 33 | + println!("Is a marathon? {}", is_a_marathon(&distance)); |
| 34 | + println!("Is a marathon? {}", is_a_marathon(&distance_km.to_miles())); |
| 35 | + // println!("Is a marathon? {}", is_a_marathon(&distance_km)); |
37 | 36 | } |
38 | 37 | ``` |
39 | 38 |
|
40 | | -Uncomment the last print statement to observe that the type supplied must be `Years`. |
| 39 | +Uncomment the last print statement to observe that the type supplied must be `Miles`. |
41 | 40 |
|
42 | 41 | To obtain the `newtype`'s value as the base type, you may use the tuple or destructuring syntax like so: |
43 | 42 |
|
44 | 43 | ```rust, editable |
45 | | -struct Years(i64); |
| 44 | +struct Miles(f64); |
46 | 45 |
|
47 | 46 | fn main() { |
48 | | - let years = Years(42); |
49 | | - let years_as_primitive_1: i64 = years.0; // Tuple |
50 | | - let Years(years_as_primitive_2) = years; // Destructuring |
| 47 | + let distance = Miles(42.0); |
| 48 | + let distance_as_primitive_1: f64 = distance.0; // Tuple |
| 49 | + let Miles(distance_as_primitive_2) = distance; // Destructuring |
51 | 50 | } |
52 | 51 | ``` |
53 | 52 |
|
|
0 commit comments