@@ -271,7 +271,7 @@ same type `T`.
271
271
Listing 10-5 shows the combined ` largest ` function definition using the generic
272
272
data type in its signature. The listing also shows how we can call the function
273
273
with either a slice of ` i32 ` values or ` char ` values. Note that this code won’t
274
- compile yet, but we’ll fix it later in this chapter .
274
+ compile yet.
275
275
276
276
src/main.rs
277
277
@@ -331,10 +331,10 @@ states that the body of `largest` won’t work for all possible types that `T`
331
331
could be. Because we want to compare values of type ` T ` in the body, we can
332
332
only use types whose values can be ordered. To enable comparisons, the standard
333
333
library has the ` std::cmp::PartialOrd ` trait that you can implement on types
334
- (see Appendix C for more on this trait). By following the help text’s
335
- suggestion, we restrict the types valid for ` T ` to only those that implement
336
- ` PartialOrd ` and this example will compile, because the standard library
337
- implements ` PartialOrd ` on both ` i32 ` and ` char ` .
334
+ (see Appendix C for more on this trait). To fix Listing 10-5, we can follow the
335
+ help text’s suggestion and restrict the types valid for ` T ` to only those that
336
+ implement ` PartialOrd ` . The listing will then compile, because the standard
337
+ library implements ` PartialOrd ` on both ` i32 ` and ` char ` .
338
338
339
339
### In Struct Definitions
340
340
@@ -669,15 +669,16 @@ define a set of behaviors necessary to accomplish some purpose.
669
669
670
670
For example, let’s say we have multiple structs that hold various kinds and
671
671
amounts of text: a ` NewsArticle ` struct that holds a news story filed in a
672
- particular location and a ` Tweet ` that can have, at most, 280 characters along
673
- with metadata that indicates whether it was a new tweet , a retweet , or a reply
674
- to another tweet .
672
+ particular location and a ` SocialPost ` that can have, at most, 280 characters
673
+ along with metadata that indicates whether it was a new post , a repost , or a
674
+ reply to another post .
675
675
676
676
We want to make a media aggregator library crate named ` aggregator ` that can
677
- display summaries of data that might be stored in a ` NewsArticle ` or ` Tweet `
678
- instance. To do this, we need a summary from each type, and we’ll request that
679
- summary by calling a ` summarize ` method on an instance. Listing 10-12 shows the
680
- definition of a public ` Summary ` trait that expresses this behavior.
677
+ display summaries of data that might be stored in a ` NewsArticle ` or
678
+ ` SocialPost ` instance. To do this, we need a summary from each type, and we’ll
679
+ request that summary by calling a ` summarize ` method on an instance. Listing
680
+ 10-12 shows the definition of a public ` Summary ` trait that expresses this
681
+ behavior.
681
682
682
683
src/lib.rs
683
684
@@ -711,8 +712,8 @@ Now that we’ve defined the desired signatures of the `Summary` trait’s metho
711
712
we can implement it on the types in our media aggregator. Listing 10-13 shows
712
713
an implementation of the ` Summary ` trait on the ` NewsArticle ` struct that uses
713
714
the headline, the author, and the location to create the return value of
714
- ` summarize ` . For the ` Tweet ` struct, we define ` summarize ` as the username
715
- followed by the entire text of the tweet , assuming that the tweet content is
715
+ ` summarize ` . For the ` SocialPost ` struct, we define ` summarize ` as the username
716
+ followed by the entire text of the post , assuming that the post content is
716
717
already limited to 280 characters.
717
718
718
719
src/lib.rs
@@ -731,21 +732,21 @@ impl Summary for NewsArticle {
731
732
}
732
733
}
733
734
734
- pub struct Tweet {
735
+ pub struct SocialPost {
735
736
pub username: String,
736
737
pub content: String,
737
738
pub reply: bool,
738
- pub retweet : bool,
739
+ pub repost : bool,
739
740
}
740
741
741
- impl Summary for Tweet {
742
+ impl Summary for SocialPost {
742
743
fn summarize(&self) -> String {
743
744
format!("{}: {}", self.username, self.content)
744
745
}
745
746
}
746
747
```
747
748
748
- Listing 10-13: Implementing the ` Summary ` trait on the ` NewsArticle ` and ` Tweet ` types
749
+ Listing 10-13: Implementing the ` Summary ` trait on the ` NewsArticle ` and ` SocialPost ` types
749
750
750
751
Implementing a trait on a type is similar to implementing regular methods. The
751
752
difference is that after ` impl ` , we put the trait name we want to implement,
@@ -756,37 +757,37 @@ signature, we use curly brackets and fill in the method body with the specific
756
757
behavior that we want the methods of the trait to have for the particular type.
757
758
758
759
Now that the library has implemented the ` Summary ` trait on ` NewsArticle ` and
759
- ` Tweet ` , users of the crate can call the trait methods on instances of
760
- ` NewsArticle ` and ` Tweet ` in the same way we call regular methods. The only
760
+ ` SocialPost ` , users of the crate can call the trait methods on instances of
761
+ ` NewsArticle ` and ` SocialPost ` in the same way we call regular methods. The only
761
762
difference is that the user must bring the trait into scope as well as the
762
763
types. Here’s an example of how a binary crate could use our ` aggregator `
763
764
library crate:
764
765
765
766
```
766
- use aggregator::{Summary, Tweet };
767
+ use aggregator::{SocialPost, Summary };
767
768
768
769
fn main() {
769
- let tweet = Tweet {
770
+ let post = SocialPost {
770
771
username: String::from("horse_ebooks"),
771
772
content: String::from(
772
773
"of course, as you probably already know, people",
773
774
),
774
775
reply: false,
775
- retweet : false,
776
+ repost : false,
776
777
};
777
778
778
- println!("1 new tweet : {}", tweet .summarize());
779
+ println!("1 new post : {}", post .summarize());
779
780
}
780
781
```
781
782
782
- This code prints ` 1 new tweet : horse_ebooks: of course, as you probably already know, people ` .
783
+ This code prints ` 1 new post : horse_ebooks: of course, as you probably already know, people ` .
783
784
784
785
Other crates that depend on the ` aggregator ` crate can also bring the ` Summary `
785
786
trait into scope to implement ` Summary ` on their own types. One restriction to
786
787
note is that we can implement a trait on a type only if either the trait or the
787
788
type, or both, are local to our crate. For example, we can implement standard
788
- library traits like ` Display ` on a custom type like ` Tweet ` as part of our
789
- ` aggregator ` crate functionality because the type ` Tweet ` is local to our
789
+ library traits like ` Display ` on a custom type like ` SocialPost ` as part of our
790
+ ` aggregator ` crate functionality because the type ` SocialPost ` is local to our
790
791
` aggregator ` crate. We can also implement ` Summary ` on ` Vec<T> ` in our
791
792
` aggregator ` crate because the trait ` Summary ` is local to our ` aggregator `
792
793
crate.
@@ -849,9 +850,10 @@ the `summarize` method on an instance of `NewsArticle`, like this:
849
850
This code prints ` New article available! (Read more...) ` .
850
851
851
852
Creating a default implementation doesn’t require us to change anything about
852
- the implementation of ` Summary ` on ` Tweet ` in Listing 10-13. The reason is that
853
- the syntax for overriding a default implementation is the same as the syntax
854
- for implementing a trait method that doesn’t have a default implementation.
853
+ the implementation of ` Summary ` on ` SocialPost ` in Listing 10-13. The reason is
854
+ that the syntax for overriding a default implementation is the same as the
855
+ syntax for implementing a trait method that doesn’t have a default
856
+ implementation.
855
857
856
858
Default implementations can call other methods in the same trait, even if those
857
859
other methods don’t have a default implementation. In this way, a trait can
@@ -875,34 +877,34 @@ To use this version of `Summary`, we only need to define `summarize_author`
875
877
when we implement the trait on a type:
876
878
877
879
```
878
- impl Summary for Tweet {
880
+ impl Summary for SocialPost {
879
881
fn summarize_author(&self) -> String {
880
882
format!("@{}", self.username)
881
883
}
882
884
}
883
885
```
884
886
885
887
After we define ` summarize_author ` , we can call ` summarize ` on instances of the
886
- ` Tweet ` struct, and the default implementation of ` summarize ` will call the
888
+ ` SocialPost ` struct, and the default implementation of ` summarize ` will call the
887
889
definition of ` summarize_author ` that we’ve provided. Because we’ve implemented
888
890
` summarize_author ` , the ` Summary ` trait has given us the behavior of the
889
891
` summarize ` method without requiring us to write any more code. Here’s what
890
892
that looks like:
891
893
892
894
```
893
- let tweet = Tweet {
895
+ let post = SocialPost {
894
896
username: String::from("horse_ebooks"),
895
897
content: String::from(
896
898
"of course, as you probably already know, people",
897
899
),
898
900
reply: false,
899
- retweet : false,
901
+ repost : false,
900
902
};
901
903
902
- println!("1 new tweet : {}", tweet .summarize());
904
+ println!("1 new post : {}", post .summarize());
903
905
```
904
906
905
- This code prints ` 1 new tweet : (Read more from @horse_ebooks...) ` .
907
+ This code prints ` 1 new post : (Read more from @horse_ebooks...) ` .
906
908
907
909
Note that it isn’t possible to call the default implementation from an
908
910
overriding implementation of that same method.
@@ -911,7 +913,7 @@ overriding implementation of that same method.
911
913
912
914
Now that you know how to define and implement traits, we can explore how to use
913
915
traits to define functions that accept many different types. We’ll use the
914
- ` Summary ` trait we implemented on the ` NewsArticle ` and ` Tweet ` types in
916
+ ` Summary ` trait we implemented on the ` NewsArticle ` and ` SocialPost ` types in
915
917
Listing 10-13 to define a ` notify ` function that calls the ` summarize ` method
916
918
on its ` item ` parameter, which is of some type that implements the ` Summary `
917
919
trait. To do this, we use the ` impl Trait ` syntax, like this:
@@ -926,7 +928,7 @@ Instead of a concrete type for the `item` parameter, we specify the `impl`
926
928
keyword and the trait name. This parameter accepts any type that implements the
927
929
specified trait. In the body of ` notify ` , we can call any methods on ` item `
928
930
that come from the ` Summary ` trait, such as ` summarize ` . We can call ` notify `
929
- and pass in any instance of ` NewsArticle ` or ` Tweet ` . Code that calls the
931
+ and pass in any instance of ` NewsArticle ` or ` SocialPost ` . Code that calls the
930
932
function with any other type, such as a ` String ` or an ` i32 ` , won’t compile
931
933
because those types don’t implement ` Summary ` .
932
934
@@ -1025,21 +1027,22 @@ value of some type that implements a trait, as shown here:
1025
1027
1026
1028
```
1027
1029
fn returns_summarizable() -> impl Summary {
1028
- Tweet {
1030
+ SocialPost {
1029
1031
username: String::from("horse_ebooks"),
1030
1032
content: String::from(
1031
1033
"of course, as you probably already know, people",
1032
1034
),
1033
1035
reply: false,
1034
- retweet : false,
1036
+ repost : false,
1035
1037
}
1036
1038
}
1037
1039
```
1038
1040
1039
1041
By using ` impl Summary ` for the return type, we specify that the
1040
1042
` returns_summarizable ` function returns some type that implements the ` Summary `
1041
1043
trait without naming the concrete type. In this case, ` returns_summarizable `
1042
- returns a ` Tweet ` , but the code calling this function doesn’t need to know that.
1044
+ returns a ` SocialPost ` , but the code calling this function doesn’t need to know
1045
+ that.
1043
1046
1044
1047
The ability to specify a return type only by the trait it implements is
1045
1048
especially useful in the context of closures and iterators, which we cover in
@@ -1049,8 +1052,8 @@ specify that a function returns some type that implements the `Iterator` trait
1049
1052
without needing to write out a very long type.
1050
1053
1051
1054
However, you can only use ` impl Trait ` if you’re returning a single type. For
1052
- example, this code that returns either a ` NewsArticle ` or a ` Tweet ` with the
1053
- return type specified as ` impl Summary ` wouldn’t work:
1055
+ example, this code that returns either a ` NewsArticle ` or a ` SocialPost ` with
1056
+ the return type specified as ` impl Summary ` wouldn’t work:
1054
1057
1055
1058
```
1056
1059
fn returns_summarizable(switch: bool) -> impl Summary {
@@ -1067,22 +1070,22 @@ fn returns_summarizable(switch: bool) -> impl Summary {
1067
1070
),
1068
1071
}
1069
1072
} else {
1070
- Tweet {
1073
+ SocialPost {
1071
1074
username: String::from("horse_ebooks"),
1072
1075
content: String::from(
1073
1076
"of course, as you probably already know, people",
1074
1077
),
1075
1078
reply: false,
1076
- retweet : false,
1079
+ repost : false,
1077
1080
}
1078
1081
}
1079
1082
}
1080
1083
```
1081
1084
1082
- Returning either a ` NewsArticle ` or a ` Tweet ` isn’t allowed due to restrictions
1083
- around how the ` impl Trait ` syntax is implemented in the compiler. We’ll cover
1084
- how to write a function with this behavior in the “Using Trait Objects That
1085
- Allow for Values of Different
1085
+ Returning either a ` NewsArticle ` or a ` SocialPost ` isn’t allowed due to
1086
+ restrictions around how the ` impl Trait ` syntax is implemented in the compiler.
1087
+ We’ll cover how to write a function with this behavior in the “Using Trait
1088
+ Objects That Allow for Values of Different
1086
1089
Types” section of Chapter 18.
1087
1090
1088
1091
### Using Trait Bounds to Conditionally Implement Methods
@@ -1173,11 +1176,12 @@ One detail we didn’t discuss in the “References and
1173
1176
Borrowing” section in Chapter 4 is
1174
1177
that every reference in Rust has a * lifetime* , which is the scope for which
1175
1178
that reference is valid. Most of the time, lifetimes are implicit and inferred,
1176
- just like most of the time, types are inferred. We must annotate types only
1177
- when multiple types are possible. In a similar way, we must annotate lifetimes
1178
- when the lifetimes of references could be related in a few different ways. Rust
1179
- requires us to annotate the relationships using generic lifetime parameters to
1180
- ensure the actual references used at runtime will definitely be valid.
1179
+ just like most of the time, types are inferred. We are only required to
1180
+ annotate types when multiple types are possible. In a similar way, we have to
1181
+ annotate lifetimes when the lifetimes of references could be related in a few
1182
+ different ways. Rust requires us to annotate the relationships using generic
1183
+ lifetime parameters to ensure the actual references used at runtime will
1184
+ definitely be valid.
1181
1185
1182
1186
Annotating lifetimes is not even a concept most other programming languages
1183
1187
have, so this is going to feel unfamiliar. Although we won’t cover lifetimes in
@@ -1338,11 +1342,7 @@ src/main.rs
1338
1342
1339
1343
```
1340
1344
fn longest(x: &str, y: &str) -> &str {
1341
- if x.len() > y.len() {
1342
- x
1343
- } else {
1344
- y
1345
- }
1345
+ if x.len() > y.len() { x } else { y }
1346
1346
}
1347
1347
```
1348
1348
@@ -1431,11 +1431,7 @@ src/main.rs
1431
1431
1432
1432
```
1433
1433
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
1434
- if x.len() > y.len() {
1435
- x
1436
- } else {
1437
- y
1438
- }
1434
+ if x.len() > y.len() { x } else { y }
1439
1435
}
1440
1436
```
1441
1437
@@ -1735,8 +1731,8 @@ fits these cases, you don’t need to write the lifetimes explicitly.
1735
1731
The elision rules don’t provide full inference. If there is still ambiguity
1736
1732
about what lifetimes the references have after Rust applies the rules, the
1737
1733
compiler won’t guess what the lifetime of the remaining references should be.
1738
- Instead of guessing, the compiler will give you an error that you can resolve
1739
- by adding the lifetime annotations.
1734
+ Instead of guessing, the compiler will give you an error that you can resolve by
1735
+ adding the lifetime annotations.
1740
1736
1741
1737
Lifetimes on function or method parameters are called * input lifetimes* , and
1742
1738
lifetimes on return values are called * output lifetimes* .
@@ -1902,11 +1898,7 @@ where
1902
1898
T: Display,
1903
1899
{
1904
1900
println!("Announcement! {ann}");
1905
- if x.len() > y.len() {
1906
- x
1907
- } else {
1908
- y
1909
- }
1901
+ if x.len() > y.len() { x } else { y }
1910
1902
}
1911
1903
```
1912
1904
0 commit comments