| <!-- DO NOT EDIT THIS FILE. |
| |
| This file is periodically generated from the content in the `/src/` |
| directory, so all fixes need to be made in `/src/`. |
| --> |
| |
| [TOC] |
| |
| ## Appendix C: Derivable Traits |
| |
| In various places in the book, we’ve discussed the `derive` attribute, which |
| you can apply to a struct or enum definition. The `derive` attribute generates |
| code that will implement a trait with its own default implementation on the |
| type you’ve annotated with the `derive` syntax. |
| |
| In this appendix, we provide a reference of all the traits in the standard |
| library that you can use with `derive`. Each section covers: |
| |
| * What operators and methods deriving this trait will enable |
| * What the implementation of the trait provided by `derive` does |
| * What implementing the trait signifies about the type |
| * The conditions in which you’re allowed or not allowed to implement the trait |
| * Examples of operations that require the trait |
| |
| If you want different behavior from that provided by the `derive` attribute, |
| consult the standard library documentation for each trait for details on how to |
| manually implement them. |
| |
| The traits listed here are the only ones defined by the standard library that |
| can be implemented on your types using `derive`. Other traits defined in the |
| standard library don’t have sensible default behavior, so it’s up to you to |
| implement them in the way that makes sense for what you’re trying to accomplish. |
| |
| An example of a trait that can’t be derived is `Display`, which handles |
| formatting for end users. You should always consider the appropriate way to |
| display a type to an end user. What parts of the type should an end user be |
| allowed to see? What parts would they find relevant? What format of the data |
| would be most relevant to them? The Rust compiler doesn’t have this insight, so |
| it can’t provide appropriate default behavior for you. |
| |
| The list of derivable traits provided in this appendix is not comprehensive: |
| libraries can implement `derive` for their own traits, making the list of |
| traits you can use `derive` with truly open ended. Implementing `derive` |
| involves using a procedural macro, which is covered in “Macros” on page XX. |
| |
| ## Debug for Programmer Output |
| |
| The `Debug` trait enables debug formatting in format strings, which you |
| indicate by adding `:?` within `{}` placeholders. |
| |
| The `Debug` trait allows you to print instances of a type for debugging |
| purposes, so you and other programmers using your type can inspect an instance |
| at a particular point in a program’s execution. |
| |
| The `Debug` trait is required, for example, in the use of the `assert_eq!` |
| macro. This macro prints the values of instances given as arguments if the |
| equality assertion fails so programmers can see why the two instances weren’t |
| equal. |
| |
| ## PartialEq and Eq for Equality Comparisons |
| |
| The `PartialEq` trait allows you to compare instances of a type to check for |
| equality and enables use of the `==` and `!=` operators. |
| |
| Deriving `PartialEq` implements the `eq` method. When `PartialEq` is derived on |
| structs, two instances are equal only if *all* fields are equal, and the |
| instances are not equal if any fields are not equal. When derived on enums, |
| each variant is equal to itself and not equal to the other variants. |
| |
| The `PartialEq` trait is required, for example, with the use of the |
| `assert_eq!` macro, which needs to be able to compare two instances of a type |
| for equality. |
| |
| The `Eq` trait has no methods. Its purpose is to signal that for every value of |
| the annotated type, the value is equal to itself. The `Eq` trait can only be |
| applied to types that also implement `PartialEq`, although not all types that |
| implement `PartialEq` can implement `Eq`. One example of this is floating-point |
| number types: the implementation of floating-point numbers states that two |
| instances of the not-a-number (`NaN`) value are not equal to each other. |
| |
| An example of when `Eq` is required is for keys in a `HashMap<K, V>` so that |
| the `HashMap<K, V>` can tell whether two keys are the same. |
| |
| ## PartialOrd and Ord for Ordering Comparisons |
| |
| The `PartialOrd` trait allows you to compare instances of a type for sorting |
| purposes. A type that implements `PartialOrd` can be used with the `<`, `>`, |
| `<=`, and `>=` operators. You can only apply the `PartialOrd` trait to types |
| that also implement `PartialEq`. |
| |
| Deriving `PartialOrd` implements the `partial_cmp` method, which returns an |
| `Option<Ordering>` that will be `None` when the values given don’t produce an |
| ordering. An example of a value that doesn’t produce an ordering, even though |
| most values of that type can be compared, is the not-a-number (`NaN`) floating |
| point value. Calling `partial_cmp` with any floating-point number and the `NaN` |
| floating-point value will return `None`. |
| |
| When derived on structs, `PartialOrd` compares two instances by comparing the |
| value in each field in the order in which the fields appear in the struct |
| definition. When derived on enums, variants of the enum declared earlier in the |
| enum definition are considered less than the variants listed later. |
| |
| The `PartialOrd` trait is required, for example, for the `gen_range` method |
| from the `rand` crate that generates a random value in the range specified by a |
| range expression. |
| |
| The `Ord` trait allows you to know that for any two values of the annotated |
| type, a valid ordering will exist. The `Ord` trait implements the `cmp` method, |
| which returns an `Ordering` rather than an `Option<Ordering>` because a valid |
| ordering will always be possible. You can only apply the `Ord` trait to types |
| that also implement `PartialOrd` and `Eq` (and `Eq` requires `PartialEq`). When |
| derived on structs and enums, `cmp` behaves the same way as the derived |
| implementation for `partial_cmp` does with `PartialOrd`. |
| |
| An example of when `Ord` is required is when storing values in a `BTreeSet<T>`, |
| a data structure that stores data based on the sort order of the values. |
| |
| ## Clone and Copy for Duplicating Values |
| |
| The `Clone` trait allows you to explicitly create a deep copy of a value, and |
| the duplication process might involve running arbitrary code and copying heap |
| data. See “Variables and Data Interacting with Clone” on page XX for more |
| information on `Clone`. |
| |
| Deriving `Clone` implements the `clone` method, which when implemented for the |
| whole type, calls `clone` on each of the parts of the type. This means all the |
| fields or values in the type must also implement `Clone` to derive `Clone`. |
| |
| An example of when `Clone` is required is when calling the `to_vec` method on a |
| slice. The slice doesn’t own the type instances it contains, but the vector |
| returned from `to_vec` will need to own its instances, so `to_vec` calls |
| `clone` on each item. Thus the type stored in the slice must implement `Clone`. |
| |
| The `Copy` trait allows you to duplicate a value by only copying bits stored on |
| the stack; no arbitrary code is necessary. See “Stack-Only Data: Copy” on page |
| XX for more information on `Copy`. |
| |
| The `Copy` trait doesn’t define any methods to prevent programmers from |
| overloading those methods and violating the assumption that no arbitrary code |
| is being run. That way, all programmers can assume that copying a value will be |
| very fast. |
| |
| You can derive `Copy` on any type whose parts all implement `Copy`. A type that |
| implements `Copy` must also implement `Clone` because a type that implements |
| `Copy` has a trivial implementation of `Clone` that performs the same task as |
| `Copy`. |
| |
| The `Copy` trait is rarely required; types that implement `Copy` have |
| optimizations available, meaning you don’t have to call `clone`, which makes |
| the code more concise. |
| |
| Everything possible with `Copy` you can also accomplish with `Clone`, but the |
| code might be slower or have to use `clone` in places. |
| |
| ## Hash for Mapping a Value to a Value of Fixed Size |
| |
| The `Hash` trait allows you to take an instance of a type of arbitrary size and |
| map that instance to a value of fixed size using a hash function. Deriving |
| `Hash` implements the `hash` method. The derived implementation of the `hash` |
| method combines the result of calling `hash` on each of the parts of the type, |
| meaning all fields or values must also implement `Hash` to derive `Hash`. |
| |
| An example of when `Hash` is required is in storing keys in a `HashMap<K, V>` |
| to store data efficiently. |
| |
| ## Default for Default Values |
| |
| The `Default` trait allows you to create a default value for a type. Deriving |
| `Default` implements the `default` function. The derived implementation of the |
| `default` function calls the `default` function on each part of the type, |
| meaning all fields or values in the type must also implement `Default` to |
| derive `Default`. |
| |
| The `Default::default` function is commonly used in combination with the struct |
| update syntax discussed in “Creating Instances from Other Instances with Struct |
| Update Syntax” on page XX. You can customize a few fields of a struct and then |
| set and use a default value for the rest of the fields by using |
| `..Default::default()`. |
| |
| The `Default` trait is required when you use the method `unwrap_or_default` on |
| `Option<T>` instances, for example. If the `Option<T>` is `None`, the method |
| `unwrap_or_default` will return the result of `Default::default` for the type |
| `T` stored in the `Option<T>`. |
| |