diff --git a/src/ch05-01-defining-structs.md b/src/ch05-01-defining-structs.md index c5db4dc74d..98ef776cc8 100644 --- a/src/ch05-01-defining-structs.md +++ b/src/ch05-01-defining-structs.md @@ -13,13 +13,13 @@ grouped together. Then, inside curly brackets, we define the names and types of the pieces of data, which we call *fields*. For example, Listing 5-1 shows a struct that stores information about a user account. -Filename: src/main.rs + ```rust {{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-01/src/main.rs:here}} ``` -Listing 5-1: A `User` struct definition + To use a struct after we’ve defined it, we create an *instance* of that struct by specifying concrete values for each of the fields. We create an instance by @@ -31,14 +31,13 @@ struct definition is like a general template for the type, and instances fill in that template with particular data to create values of the type. For example, we can declare a particular user as shown in Listing 5-2. -Filename: src/main.rs + ```rust {{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-02/src/main.rs:here}} ``` -Listing 5-2: Creating an instance of the `User` -struct + To get a specific value from a struct, we use dot notation. For example, to access this user’s email address, we use `user1.email`. If the instance is @@ -46,14 +45,13 @@ mutable, we can change a value by using the dot notation and assigning into a particular field. Listing 5-3 shows how to change the value in the `email` field of a mutable `User` instance. -Filename: src/main.rs + ```rust {{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-03/src/main.rs:here}} ``` -Listing 5-3: Changing the value in the `email` field of a -`User` instance + Note that the entire instance must be mutable; Rust doesn’t allow us to mark only certain fields as mutable. As with any expression, we can construct a new @@ -64,14 +62,13 @@ Listing 5-4 shows a `build_user` function that returns a `User` instance with the given email and username. The `active` field gets the value of `true`, and the `sign_in_count` gets a value of `1`. -Filename: src/main.rs + ```rust {{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-04/src/main.rs:here}} ``` -Listing 5-4: A `build_user` function that takes an email -and username and returns a `User` instance + It makes sense to name the function parameters with the same name as the struct fields, but having to repeat the `email` and `username` field names and @@ -88,15 +85,13 @@ Listing 5-4, we can use the *field init shorthand* syntax to rewrite `build_user` so it behaves exactly the same but doesn’t have the repetition of `username` and `email`, as shown in Listing 5-5. -Filename: src/main.rs + ```rust {{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-05/src/main.rs:here}} ``` -Listing 5-5: A `build_user` function that uses field init -shorthand because the `username` and `email` parameters have the same name as -struct fields + Here, we’re creating a new instance of the `User` struct, which has a field named `email`. We want to set the `email` field’s value to the value in the @@ -114,28 +109,25 @@ First, in Listing 5-6 we show how to create a new `User` instance in `user2` regularly, without the update syntax. We set a new value for `email` but otherwise use the same values from `user1` that we created in Listing 5-2. -Filename: src/main.rs + ```rust {{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-06/src/main.rs:here}} ``` -Listing 5-6: Creating a new `User` instance using all but one of -the values from `user1` + Using struct update syntax, we can achieve the same effect with less code, as shown in Listing 5-7. The syntax `..` specifies that the remaining fields not explicitly set should have the same value as the fields in the given instance. -Filename: src/main.rs + ```rust {{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-07/src/main.rs:here}} ``` -Listing 5-7: Using struct update syntax to set a new -`email` value for a `User` instance but to use the rest of the values from -`user1` + The code in Listing 5-7 also creates an instance in `user2` that has a different value for `email` but has the same values for the `username`, @@ -169,12 +161,14 @@ To define a tuple struct, start with the `struct` keyword and the struct name followed by the types in the tuple. For example, here we define and use two tuple structs named `Color` and `Point`: -Filename: src/main.rs + ```rust {{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/no-listing-01-tuple-structs/src/main.rs}} ``` + + Note that the `black` and `origin` values are different types because they’re instances of different tuple structs. Each struct you define is its own type, even though the fields within the struct might have the same types. For @@ -194,12 +188,14 @@ have any data that you want to store in the type itself. We’ll discuss traits in Chapter 10. Here’s an example of declaring and instantiating a unit struct named `AlwaysEqual`: -Filename: src/main.rs + ```rust {{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/no-listing-04-unit-like-structs/src/main.rs}} ``` + + To define `AlwaysEqual`, we use the `struct` keyword, the name we want, and then a semicolon. No need for curly brackets or parentheses! Then we can get an instance of `AlwaysEqual` in the `subject` variable in a similar way: using the @@ -223,7 +219,7 @@ implement them on any type, including unit-like structs. > is valid for as long as the struct is. Let’s say you try to store a reference > in a struct without specifying lifetimes, like the following; this won’t work: > -> Filename: src/main.rs +> > > > @@ -245,6 +241,8 @@ implement them on any type, including unit-like structs. > } > ``` > +> +> > The compiler will complain that it needs lifetime specifiers: > > ```console diff --git a/src/ch05-02-example-structs.md b/src/ch05-02-example-structs.md index 1e7c9f7e9b..392f1bd3bd 100644 --- a/src/ch05-02-example-structs.md +++ b/src/ch05-02-example-structs.md @@ -9,14 +9,13 @@ the width and height of a rectangle specified in pixels and calculate the area of the rectangle. Listing 5-8 shows a short program with one way of doing exactly that in our project’s *src/main.rs*. -Filename: src/main.rs + ```rust {{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-08/src/main.rs:all}} ``` -Listing 5-8: Calculating the area of a rectangle -specified by separate width and height variables + Now, run this program using `cargo run`: @@ -45,14 +44,13 @@ of Chapter 3: by using tuples. Listing 5-9 shows another version of our program that uses tuples. -Filename: src/main.rs + ```rust {{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-09/src/main.rs}} ``` -Listing 5-9: Specifying the width and height of the -rectangle with a tuple + In one way, this program is better. Tuples let us add a bit of structure, and we’re now passing just one argument. But in another way, this version is less @@ -72,13 +70,13 @@ We use structs to add meaning by labeling the data. We can transform the tuple we’re using into a struct with a name for the whole as well as names for the parts, as shown in Listing 5-10. -Filename: src/main.rs + ```rust {{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-10/src/main.rs}} ``` -Listing 5-10: Defining a `Rectangle` struct + Here we’ve defined a struct and named it `Rectangle`. Inside the curly brackets, we defined the fields as `width` and `height`, both of which have @@ -108,14 +106,13 @@ debugging our program and see the values for all its fields. Listing 5-11 tries using the [`println!` macro][println] as we have used in previous chapters. This won’t work, however. -Filename: src/main.rs + ```rust,ignore,does_not_compile {{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-11/src/main.rs}} ``` -Listing 5-11: Attempting to print a `Rectangle` -instance + When we compile this code, we get an error with this core message: @@ -163,14 +160,13 @@ have to explicitly opt in to make that functionality available for our struct. To do that, we add the outer attribute `#[derive(Debug)]` just before the struct definition, as shown in Listing 5-12. -Filename: src/main.rs + ```rust {{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-12/src/main.rs}} ``` -Listing 5-12: Adding the attribute to derive the `Debug` -trait and printing the `Rectangle` instance using debug formatting + Now when we run the program, we won’t get any errors, and we’ll see the following output: diff --git a/src/ch05-03-method-syntax.md b/src/ch05-03-method-syntax.md index d25e55b18c..91887210d2 100644 --- a/src/ch05-03-method-syntax.md +++ b/src/ch05-03-method-syntax.md @@ -15,14 +15,13 @@ Let’s change the `area` function that has a `Rectangle` instance as a paramete and instead make an `area` method defined on the `Rectangle` struct, as shown in Listing 5-13. -Filename: src/main.rs + ```rust {{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-13/src/main.rs}} ``` -Listing 5-13: Defining an `area` method on the -`Rectangle` struct + To define the function within the context of `Rectangle`, we start an `impl` (implementation) block for `Rectangle`. Everything within this `impl` block @@ -65,12 +64,14 @@ Note that we can choose to give a method the same name as one of the struct’s fields. For example, we can define a method on `Rectangle` that is also named `width`: -Filename: src/main.rs + ```rust {{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/no-listing-06-method-field-interaction/src/main.rs:here}} ``` + + Here, we’re choosing to make the `width` method return `true` if the value in the instance’s `width` field is greater than `0` and `false` if the value is `0`: we can use a field within a method of the same name for any purpose. In @@ -141,14 +142,13 @@ within `self` (the first `Rectangle`); otherwise, it should return `false`. That is, once we’ve defined the `can_hold` method, we want to be able to write the program shown in Listing 5-14. -Filename: src/main.rs + ```rust,ignore {{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-14/src/main.rs}} ``` -Listing 5-14: Using the as-yet-unwritten `can_hold` -method + The expected output would look like the following because both dimensions of `rect2` are smaller than the dimensions of `rect1`, but `rect3` is wider than @@ -173,14 +173,13 @@ Boolean, and the implementation will check whether the width and height of respectively. Let’s add the new `can_hold` method to the `impl` block from Listing 5-13, shown in Listing 5-15. -Filename: src/main.rs + ```rust {{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-15/src/main.rs:here}} ``` -Listing 5-15: Implementing the `can_hold` method on -`Rectangle` that takes another `Rectangle` instance as a parameter + When we run this code with the `main` function in Listing 5-14, we’ll get our desired output. Methods can take multiple parameters that we add to the @@ -226,12 +225,13 @@ Each struct is allowed to have multiple `impl` blocks. For example, Listing 5-15 is equivalent to the code shown in Listing 5-16, which has each method in its own `impl` block. ++ ```rust {{#rustdoc_include ../listings/ch05-using-structs-to-structure-related-data/listing-05-16/src/main.rs:here}} ``` -Listing 5-16: Rewriting Listing 5-15 using multiple `impl` -blocks + There’s no reason to separate these methods into multiple `impl` blocks here, but this is valid syntax. We’ll see a case in which multiple `impl` blocks are