From 62ca2eeb44ac1b858c332dcc2d63bfee796a0024 Mon Sep 17 00:00:00 2001 From: "Carol (Nichols || Goulding)" Date: Tue, 2 Jan 2018 15:40:00 -0500 Subject: [PATCH] Edits to associated types --- second-edition/nostarch/chapter19.md | 70 ++++++++++-------- second-edition/src/ch19-03-advanced-traits.md | 72 +++++++++++-------- 2 files changed, 85 insertions(+), 57 deletions(-) diff --git a/second-edition/nostarch/chapter19.md b/second-edition/nostarch/chapter19.md index f89c28738..fe1b15f33 100644 --- a/second-edition/nostarch/chapter19.md +++ b/second-edition/nostarch/chapter19.md @@ -1050,24 +1050,31 @@ Next, let’s take a look at some other advanced features dealing with traits! ## Advanced Traits -We covered traits in Chapter 10, but like lifetimes, we didn’t get to all the -details. Now that we know more Rust, we can get into the nitty-gritty. +We covered traits in Chapter 10 but, like lifetimes, we didn’t get to some of +the more advanced details. Now that we know more Rust, we can get into the +nitty-gritty. -### Associated Types +### Associated Types Specify Placeholder Types in Trait Definitions *Associated types* are a way of associating a type placeholder with a trait such that the trait method definitions can use these placeholder types in their signatures. The implementor of a trait will specify the concrete type to be -used in this type’s place for the particular implementation. +used in this type’s place for the particular implementation. That way, we can +define a trait that uses some types without needing to know exactly what those +types are until the trait is implemented. -We’ve described most of the things in this chapter as being very rare. -Associated types are somewhere in the middle; they’re more rare than the rest -of the book, but more common than many of the things in this chapter. + + -An example of a trait with an associated type is the `Iterator` trait provided -by the standard library. It has an associated type named `Item` that stands in -for the type of the values that we’re iterating over. We mentioned in Chapter -13 that the definition of the `Iterator` trait is as shown in Listing 19-20: +We’ve described most of the things in this chapter as being needed very rarely. +Associated types are somewhere in the middle; they’re used more rarely than the +rest of the book, but more commonly than many of the things in this chapter. + +One example of a trait with an associated type is the `Iterator` trait provided +by the standard library. This has an associated type named `Item` that stands +in for the type of the values it's iterating over. We mentioned in Chapter 13 +that the definition of the `Iterator` trait is as shown in Listing 19-20: ``` pub trait Iterator { @@ -1079,16 +1086,20 @@ pub trait Iterator { Listing 19-20: The definition of the `Iterator` trait that has an associated type `Item` -This says that the `Iterator` trait has an associated type named `Item`. `Item` -is a placeholder type, and the return value of the `next` method will return -values of type `Option`. Implementors of this trait will specify -the concrete type for `Item`, and the `next` method will return an `Option` -containing a value of whatever type the implementor has specified. +The `Iterator` trait has an associated type named `Item`. This is a placeholder +type, and the `next` method will return values of type `Option`. +Implementors of this trait will specify the concrete type for `Item`, and the +`next` method will return an `Option` containing a value of that concrete type. #### Associated Types Versus Generics -When we implemented the `Iterator` trait on the `Counter` struct in Listing -13-6, we specified that the `Item` type was `u32`: +This may seem like a similar concept to generics, in that it allows us to +define a function without specifying what types it can deal with. So why use +associated types? + +Let's examine the difference with an example that implements the `Iterator` +trait on the `Counter` struct. In Listing 13-6, we specified that the `Item` +type was `u32`: ``` impl Iterator for Counter { @@ -1097,8 +1108,8 @@ impl Iterator for Counter { fn next(&mut self) -> Option { ``` -This feels similar to generics. So why isn’t the `Iterator` trait defined as -shown in Listing 19-21? +This feels similar to generics. So why not just define the `Iterator` trait +with generics as shown in Listing 19-21? ``` pub trait Iterator { @@ -1108,17 +1119,18 @@ pub trait Iterator { Listing 19-21: A hypothetical definition of the `Iterator` trait using generics -The difference is that with the definition in Listing 19-21, we could also -implement `Iterator for Counter`, or any other type as well, so that -we’d have multiple implementations of `Iterator` for `Counter`. In other words, -when a trait has a generic parameter, we can implement that trait for a type -multiple times, changing the generic type parameters’ concrete types each time. -Then when we use the `next` method on `Counter`, we’d have to provide type +The difference lies in the fact that when using generics like in Listing 19-21, +we have to annotate the types in each implementation. This is because we can +also implement `Iterator for Counter`, or any other type, which would +give us multiple implementations of `Iterator` for `Counter`. In other words, +when a trait has a generic parameter, it can be implemented for a type multiple +times, changing the concrete types of the generic type parameters each time. +When we use the `next` method on `Counter`, we’d then have to provide type annotations to indicate which implementation of `Iterator` we wanted to use. -With associated types, we can’t implement a trait on a type multiple times. -Using the actual definition of `Iterator` from Listing 19-20, we can only -choose once what the type of `Item` will be, since there can only be one `impl +With associated types, we don't need to annotate types because we can’t +implement a trait on a type multiple times. With Listing 19-20, we can only +choose once what the type of `Item` will be, because there can only be one `impl Iterator for Counter`. We don’t have to specify that we want an iterator of `u32` values everywhere that we call `next` on `Counter`. diff --git a/second-edition/src/ch19-03-advanced-traits.md b/second-edition/src/ch19-03-advanced-traits.md index 5eda79bc3..84d4f8661 100644 --- a/second-edition/src/ch19-03-advanced-traits.md +++ b/second-edition/src/ch19-03-advanced-traits.md @@ -1,23 +1,31 @@ ## Advanced Traits -We covered traits in Chapter 10, but like lifetimes, we didn’t get to all the +We first covered traits in the “Traits: Defining Shared Behavior” section of +Chapter 10 but, like lifetimes, we didn’t get to some of the more advanced details. Now that we know more Rust, we can get into the nitty-gritty. -### Associated Types +### Associated Types Specify Placeholder Types in Trait Definitions *Associated types* are a way of associating a type placeholder with a trait such that the trait method definitions can use these placeholder types in their signatures. The implementor of a trait will specify the concrete type to be -used in this type’s place for the particular implementation. +used in this type’s place for the particular implementation. That way, we can +define a trait that uses some types without needing to know exactly what those +types are until the trait is implemented. -We’ve described most of the things in this chapter as being very rare. -Associated types are somewhere in the middle; they’re more rare than the rest -of the book, but more common than many of the things in this chapter. + + -An example of a trait with an associated type is the `Iterator` trait provided -by the standard library. It has an associated type named `Item` that stands in -for the type of the values that we’re iterating over. We mentioned in Chapter -13 that the definition of the `Iterator` trait is as shown in Listing 19-20: +We’ve described most of the things in this chapter as being needed very rarely. +Associated types are somewhere in the middle; they’re used more rarely than the +rest of the book, but more commonly than many of the things in this chapter. + +One example of a trait with an associated type is the `Iterator` trait provided +by the standard library. This has an associated type named `Item` that stands +in for the type of the values it’s iterating over. In “The `Iterator` Trait and +the `next` Method” section of Chapter 13, we mentioned that the definition of +the `Iterator` trait is as shown in Listing 19-20: ```rust pub trait Iterator { @@ -29,26 +37,33 @@ pub trait Iterator { Listing 19-20: The definition of the `Iterator` trait that has an associated type `Item` -This says that the `Iterator` trait has an associated type named `Item`. `Item` -is a placeholder type, and the return value of the `next` method will return -values of type `Option`. Implementors of this trait will specify -the concrete type for `Item`, and the `next` method will return an `Option` -containing a value of whatever type the implementor has specified. +The `Iterator` trait has an associated type named `Item`. This is a placeholder +type, and the `next` method will return values of type `Option`. +Implementors of this trait will specify the concrete type for `Item`, and the +`next` method will return an `Option` containing a value of that concrete type. #### Associated Types Versus Generics -When we implemented the `Iterator` trait on the `Counter` struct in Listing -13-6, we specified that the `Item` type was `u32`: +This may seem like a similar concept to generics, in that it allows us to +define a function without specifying what types it can deal with. So why use +associated types? + +Let’s examine the difference with an example that implements the `Iterator` +trait on the `Counter` struct from Chapter 13. In Listing 13-21, we specified +that the `Item` type was `u32`: + +Filename: src/lib.rs ```rust,ignore impl Iterator for Counter { type Item = u32; fn next(&mut self) -> Option { + // --snip-- ``` -This feels similar to generics. So why isn’t the `Iterator` trait defined as -shown in Listing 19-21? +This feels similar to generics. So why not just define the `Iterator` trait +with generics as shown in Listing 19-21? ```rust pub trait Iterator { @@ -59,17 +74,18 @@ pub trait Iterator { Listing 19-21: A hypothetical definition of the `Iterator` trait using generics -The difference is that with the definition in Listing 19-21, we could also -implement `Iterator for Counter`, or any other type as well, so that -we’d have multiple implementations of `Iterator` for `Counter`. In other words, -when a trait has a generic parameter, we can implement that trait for a type -multiple times, changing the generic type parameters’ concrete types each time. -Then when we use the `next` method on `Counter`, we’d have to provide type +The difference lies in the fact that when using generics like in Listing 19-21, +we have to annotate the types in each implementation. This is because we can +also implement `Iterator for Counter`, or any other type, which would +give us multiple implementations of `Iterator` for `Counter`. In other words, +when a trait has a generic parameter, it can be implemented for a type multiple +times, changing the concrete types of the generic type parameters each time. +When we use the `next` method on `Counter`, we’d then have to provide type annotations to indicate which implementation of `Iterator` we wanted to use. -With associated types, we can’t implement a trait on a type multiple times. -Using the actual definition of `Iterator` from Listing 19-20, we can only -choose once what the type of `Item` will be, since there can only be one `impl +With associated types, we don’t need to annotate types because we can’t +implement a trait on a type multiple times. With Listing 19-20, we can only +choose once what the type of `Item` will be, because there can only be one `impl Iterator for Counter`. We don’t have to specify that we want an iterator of `u32` values everywhere that we call `next` on `Counter`.