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