]>
Commit | Line | Data |
---|---|---|
94b46f34 XL |
1 | ## Appendix C: Derivable Traits |
2 | ||
3 | In various places in the book, we’ve discussed the `derive` attribute, which | |
4 | you can apply to a struct or enum definition. The `derive` attribute generates | |
5 | code that will implement a trait with its own default implementation on the | |
6 | type you’ve annotated with the `derive` syntax. | |
7 | ||
8 | In this appendix, we provide a reference of all the traits in the standard | |
9 | library that you can use with `derive`. Each section covers: | |
10 | ||
11 | * What operators and methods deriving this trait will enable | |
12 | * What the implementation of the trait provided by `derive` does | |
13 | * What implementing the trait signifies about the type | |
14 | * The conditions in which you’re allowed or not allowed to implement the trait | |
15 | * Examples of operations that require the trait | |
83c7162d XL |
16 | |
17 | If you want different behavior than that provided by the `derive` attribute, | |
94b46f34 | 18 | consult the standard library documentation for each trait for details on how to |
83c7162d XL |
19 | manually implement them. |
20 | ||
83c7162d XL |
21 | The rest of the traits defined in the standard library can’t be implemented on |
22 | your types using `derive`. These traits don’t have sensible default behavior, | |
23 | so it’s up to you to implement them in the way that makes sense for what you’re | |
24 | trying to accomplish. | |
25 | ||
26 | An example of a trait that can’t be derived is `Display`, which handles | |
94b46f34 XL |
27 | formatting for end users. You should always consider the appropriate way to |
28 | display a type to an end user. What parts of the type should an end user be | |
29 | allowed to see? What parts would they find relevant? What format of the data | |
30 | would be most relevant to them? The Rust compiler doesn’t have this insight, so | |
31 | it can’t provide appropriate default behavior for you. | |
83c7162d XL |
32 | |
33 | The list of derivable traits provided in this appendix is not comprehensive: | |
94b46f34 XL |
34 | libraries can implement `derive` for their own traits, making the list of |
35 | traits you can use `derive` with truly open-ended. Implementing `derive` | |
36 | involves using a procedural macro, which is covered in Appendix D. | |
83c7162d XL |
37 | |
38 | ### `Debug` for Programmer Output | |
39 | ||
94b46f34 XL |
40 | The `Debug` trait enables debug formatting in format strings, which you |
41 | indicate by adding `:?` within `{}` placeholders. | |
83c7162d XL |
42 | |
43 | The `Debug` trait allows you to print instances of a type for debugging | |
44 | purposes, so you and other programmers using your type can inspect an instance | |
45 | at a particular point in a program’s execution. | |
46 | ||
94b46f34 XL |
47 | The `Debug` trait is required, for example, in use of the `assert_eq!` macro. |
48 | This macro prints the values of instances given as arguments if the equality | |
49 | assertion fails so programmers can see why the two instances weren’t equal. | |
83c7162d XL |
50 | |
51 | ### `PartialEq` and `Eq` for Equality Comparisons | |
52 | ||
83c7162d | 53 | The `PartialEq` trait allows you to compare instances of a type to check for |
94b46f34 | 54 | equality and enables use of the `==` and `!=` operators. |
83c7162d XL |
55 | |
56 | Deriving `PartialEq` implements the `eq` method. When `PartialEq` is derived on | |
94b46f34 XL |
57 | structs, two instances are equal only if *all* fields are equal, and the |
58 | instances are not equal if any fields are not equal. When derived on enums, | |
59 | each variant is equal to itself and not equal to the other variants. | |
83c7162d | 60 | |
94b46f34 XL |
61 | The `PartialEq` trait is required, for example, with the use of the |
62 | `assert_eq!` macro, which needs to be able to compare two instances of a type | |
63 | for equality. | |
83c7162d XL |
64 | |
65 | The `Eq` trait has no methods. Its purpose is to signal that for every value of | |
66 | the annotated type, the value is equal to itself. The `Eq` trait can only be | |
94b46f34 | 67 | applied to types that also implement `PartialEq`, although not all types that |
83c7162d | 68 | implement `PartialEq` can implement `Eq`. One example of this is floating point |
94b46f34 XL |
69 | number types: the implementation of floating point numbers states that two |
70 | instances of the not-a-number (`NaN`) value are not equal to each other. | |
83c7162d | 71 | |
94b46f34 XL |
72 | An example of when `Eq` is required is for keys in a `HashMap<K, V>` so the |
73 | `HashMap<K, V>` can tell whether two keys are the same. | |
83c7162d XL |
74 | |
75 | ### `PartialOrd` and `Ord` for Ordering Comparisons | |
76 | ||
77 | The `PartialOrd` trait allows you to compare instances of a type for sorting | |
94b46f34 XL |
78 | purposes. A type that implements `PartialOrd` can be used with the `<`, `>`, |
79 | `<=`, and `>=` operators. You can only apply the `PartialOrd` trait to types | |
83c7162d XL |
80 | that also implement `PartialEq`. |
81 | ||
82 | Deriving `PartialOrd` implements the `partial_cmp` method, which returns an | |
94b46f34 | 83 | `Option<Ordering>` that will be `None` when the values given don’t produce an |
83c7162d XL |
84 | ordering. An example of a value that doesn’t produce an ordering, even though |
85 | most values of that type can be compared, is the not-a-number (`NaN`) floating | |
86 | point value. Calling `partial_cmp` with any floating point number and the `NaN` | |
87 | floating point value will return `None`. | |
88 | ||
83c7162d XL |
89 | When derived on structs, `PartialOrd` compares two instances by comparing the |
90 | value in each field in the order in which the fields appear in the struct | |
91 | definition. When derived on enums, variants of the enum declared earlier in the | |
94b46f34 | 92 | enum definition are considered less than the variants listed later. |
83c7162d | 93 | |
94b46f34 XL |
94 | The `PartialOrd` trait is required, for example, for the `gen_range` method |
95 | from the `rand` crate that generates a random value in the range specified by a | |
96 | low value and a high value. | |
83c7162d XL |
97 | |
98 | The `Ord` trait allows you to know that for any two values of the annotated | |
99 | type, a valid ordering will exist. The `Ord` trait implements the `cmp` method, | |
100 | which returns an `Ordering` rather than an `Option<Ordering>` because a valid | |
94b46f34 | 101 | ordering will always be possible. You can only apply the `Ord` trait to types |
83c7162d XL |
102 | that also implement `PartialOrd` and `Eq` (and `Eq` requires `PartialEq`). When |
103 | derived on structs and enums, `cmp` behaves the same way as the derived | |
104 | implementation for `partial_cmp` does with `PartialOrd`. | |
105 | ||
106 | An example of when `Ord` is required is when storing values in a `BTreeSet<T>`, | |
107 | a data structure that stores data based on the sort order of the values. | |
108 | ||
109 | ### `Clone` and `Copy` for Duplicating Values | |
110 | ||
83c7162d XL |
111 | The `Clone` trait allows you to explicitly create a deep copy of a value, and |
112 | the duplication process might involve running arbitrary code and copying heap | |
113 | data. See the “Ways Variables and Data Interact: Clone” section in Chapter 4 | |
114 | for more information on `Clone`. | |
115 | ||
94b46f34 XL |
116 | Deriving `Clone` implements the `clone` method, which when implemented for the |
117 | whole type, calls `clone` on each of the parts of the type. This means all the | |
118 | fields or values in the type must also implement `Clone` to derive `Clone`. | |
83c7162d XL |
119 | |
120 | An example of when `Clone` is required is when calling the `to_vec` method on a | |
121 | slice. The slice doesn’t own the type instances it contains, but the vector | |
122 | returned from `to_vec` will need to own its instances, so `to_vec` calls | |
123 | `clone` on each item. Thus, the type stored in the slice must implement `Clone`. | |
124 | ||
125 | The `Copy` trait allows you to duplicate a value by only copying bits stored on | |
126 | the stack; no arbitrary code is necessary. See the “Stack-Only Data: Copy” | |
127 | section in Chapter 4 for more information on `Copy`. | |
128 | ||
94b46f34 XL |
129 | The `Copy` trait doesn’t define any methods to prevent programmers from |
130 | overloading those methods and violating the assumption that no arbitrary code | |
131 | is being run. That way, all programmers can assume that copying a value will be | |
83c7162d XL |
132 | very fast. |
133 | ||
94b46f34 XL |
134 | You can derive `Copy` on any type whose parts all implement `Copy`. You can |
135 | only apply the `Copy` trait to types that also implement `Clone`, because a | |
136 | type that implements `Copy` has a trivial implementation of `Clone` that | |
137 | performs the same task as `Copy`. | |
83c7162d | 138 | |
94b46f34 XL |
139 | The `Copy` trait is rarely required; types that implement `Copy` have |
140 | optimizations available, meaning you don’t have to call `clone`, which makes | |
141 | the code more concise. | |
83c7162d | 142 | |
94b46f34 | 143 | Everything possible with `Copy` you can also accomplish with `Clone`, but the |
83c7162d XL |
144 | code might be slower or have to use `clone` in places. |
145 | ||
146 | ### `Hash` for Mapping a Value to a Value of Fixed Size | |
147 | ||
148 | The `Hash` trait allows you to take an instance of a type of arbitrary size and | |
94b46f34 | 149 | map that instance to a value of fixed size using a hash function. Deriving |
83c7162d XL |
150 | `Hash` implements the `hash` method. The derived implementation of the `hash` |
151 | method combines the result of calling `hash` on each of the parts of the type, | |
152 | meaning all fields or values must also implement `Hash` to derive `Hash`. | |
153 | ||
94b46f34 XL |
154 | An example of when `Hash` is required is in storing keys in a `HashMap<K, V>` |
155 | to store data efficiently. | |
83c7162d XL |
156 | |
157 | ### `Default` for Default Values | |
158 | ||
159 | The `Default` trait allows you to create a default value for a type. Deriving | |
94b46f34 XL |
160 | `Default` implements the `default` function. The derived implementation of the |
161 | `default` function calls the `default` function on each part of the type, | |
162 | meaning all fields or values in the type must also implement `Default` to | |
163 | derive `Default.` | |
164 | ||
165 | The `Default::default` function is commonly used in combination with the struct | |
166 | update syntax discussed in the “Creating Instances From Other Instances With | |
167 | Struct Update Syntax” section in Chapter 5. You can customize a few fields of a | |
168 | struct and then set and use a default value for the rest of the fields by using | |
83c7162d XL |
169 | `..Default::default()`. |
170 | ||
94b46f34 XL |
171 | The `Default` trait is required when you use the method `unwrap_or_default` on |
172 | `Option<T>` instances, for example. If the `Option<T>` is `None`, the method | |
173 | `unwrap_or_default` will return the result of `Default::default` for the type | |
174 | `T` stored in the `Option<T>`. |