152 lines
12 KiB
HTML
152 lines
12 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<title>C - Derivable Traits</title>
|
||
</head>
|
||
<body>
|
||
<h2 id="appendix-c-derivable-traits"><a class="header" href="#appendix-c-derivable-traits">Appendix C: Derivable Traits</a></h2>
|
||
<p>In various places in the book, we’ve discussed the <code>derive</code> attribute, which
|
||
you can apply to a struct or enum definition. The <code>derive</code> attribute generates
|
||
code that will implement a trait with its own default implementation on the
|
||
type you’ve annotated with the <code>derive</code> syntax.</p>
|
||
<p>In this appendix, we provide a reference of all the traits in the standard
|
||
library that you can use with <code>derive</code>. Each section covers:</p>
|
||
<ul>
|
||
<li>What operators and methods deriving this trait will enable</li>
|
||
<li>What the implementation of the trait provided by <code>derive</code> does</li>
|
||
<li>What implementing the trait signifies about the type</li>
|
||
<li>The conditions in which you’re allowed or not allowed to implement the trait</li>
|
||
<li>Examples of operations that require the trait</li>
|
||
</ul>
|
||
<p>If you want different behavior from that provided by the <code>derive</code> attribute,
|
||
consult the <a href="../std/index.html">standard library documentation</a><!-- ignore -->
|
||
for each trait for details on how to manually implement them.</p>
|
||
<p>The traits listed here are the only ones defined by the standard library that
|
||
can be implemented on your types using <code>derive</code>. 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.</p>
|
||
<p>An example of a trait that can’t be derived is <code>Display</code>, 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.</p>
|
||
<p>The list of derivable traits provided in this appendix is not comprehensive:
|
||
Libraries can implement <code>derive</code> for their own traits, making the list of
|
||
traits you can use <code>derive</code> with truly open ended. Implementing <code>derive</code>
|
||
involves using a procedural macro, which is covered in the <a href="../ch20/ch20-05-macros.html#custom-derive-macros">“Custom <code>derive</code>
|
||
Macros”</a><!-- ignore --> section in Chapter 20.</p>
|
||
<h3 id="debug-for-programmer-output"><a class="header" href="#debug-for-programmer-output"><code>Debug</code> for Programmer Output</a></h3>
|
||
<p>The <code>Debug</code> trait enables debug formatting in format strings, which you
|
||
indicate by adding <code>:?</code> within <code>{}</code> placeholders.</p>
|
||
<p>The <code>Debug</code> 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.</p>
|
||
<p>The <code>Debug</code> trait is required, for example, in the use of the <code>assert_eq!</code>
|
||
macro. This macro prints the values of instances given as arguments if the
|
||
equality assertion fails so that programmers can see why the two instances
|
||
weren’t equal.</p>
|
||
<h3 id="partialeq-and-eq-for-equality-comparisons"><a class="header" href="#partialeq-and-eq-for-equality-comparisons"><code>PartialEq</code> and <code>Eq</code> for Equality Comparisons</a></h3>
|
||
<p>The <code>PartialEq</code> trait allows you to compare instances of a type to check for
|
||
equality and enables use of the <code>==</code> and <code>!=</code> operators.</p>
|
||
<p>Deriving <code>PartialEq</code> implements the <code>eq</code> method. When <code>PartialEq</code> is derived on
|
||
structs, two instances are equal only if <em>all</em> fields are equal, and the
|
||
instances are not equal if <em>any</em> fields are not equal. When derived on enums,
|
||
each variant is equal to itself and not equal to the other variants.</p>
|
||
<p>The <code>PartialEq</code> trait is required, for example, with the use of the
|
||
<code>assert_eq!</code> macro, which needs to be able to compare two instances of a type
|
||
for equality.</p>
|
||
<p>The <code>Eq</code> trait has no methods. Its purpose is to signal that for every value of
|
||
the annotated type, the value is equal to itself. The <code>Eq</code> trait can only be
|
||
applied to types that also implement <code>PartialEq</code>, although not all types that
|
||
implement <code>PartialEq</code> can implement <code>Eq</code>. One example of this is floating-point
|
||
number types: The implementation of floating-point numbers states that two
|
||
instances of the not-a-number (<code>NaN</code>) value are not equal to each other.</p>
|
||
<p>An example of when <code>Eq</code> is required is for keys in a <code>HashMap<K, V></code> so that
|
||
the <code>HashMap<K, V></code> can tell whether two keys are the same.</p>
|
||
<h3 id="partialord-and-ord-for-ordering-comparisons"><a class="header" href="#partialord-and-ord-for-ordering-comparisons"><code>PartialOrd</code> and <code>Ord</code> for Ordering Comparisons</a></h3>
|
||
<p>The <code>PartialOrd</code> trait allows you to compare instances of a type for sorting
|
||
purposes. A type that implements <code>PartialOrd</code> can be used with the <code><</code>, <code>></code>,
|
||
<code><=</code>, and <code>>=</code> operators. You can only apply the <code>PartialOrd</code> trait to types
|
||
that also implement <code>PartialEq</code>.</p>
|
||
<p>Deriving <code>PartialOrd</code> implements the <code>partial_cmp</code> method, which returns an
|
||
<code>Option<Ordering></code> that will be <code>None</code> 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 <code>NaN</code> floating point value.
|
||
Calling <code>partial_cmp</code> with any floating-point number and the <code>NaN</code>
|
||
floating-point value will return <code>None</code>.</p>
|
||
<p>When derived on structs, <code>PartialOrd</code> 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.</p>
|
||
<p>The <code>PartialOrd</code> trait is required, for example, for the <code>gen_range</code> method
|
||
from the <code>rand</code> crate that generates a random value in the range specified by a
|
||
range expression.</p>
|
||
<p>The <code>Ord</code> trait allows you to know that for any two values of the annotated
|
||
type, a valid ordering will exist. The <code>Ord</code> trait implements the <code>cmp</code> method,
|
||
which returns an <code>Ordering</code> rather than an <code>Option<Ordering></code> because a valid
|
||
ordering will always be possible. You can only apply the <code>Ord</code> trait to types
|
||
that also implement <code>PartialOrd</code> and <code>Eq</code> (and <code>Eq</code> requires <code>PartialEq</code>). When
|
||
derived on structs and enums, <code>cmp</code> behaves the same way as the derived
|
||
implementation for <code>partial_cmp</code> does with <code>PartialOrd</code>.</p>
|
||
<p>An example of when <code>Ord</code> is required is when storing values in a <code>BTreeSet<T></code>,
|
||
a data structure that stores data based on the sort order of the values.</p>
|
||
<h3 id="clone-and-copy-for-duplicating-values"><a class="header" href="#clone-and-copy-for-duplicating-values"><code>Clone</code> and <code>Copy</code> for Duplicating Values</a></h3>
|
||
<p>The <code>Clone</code> 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 the <a href="../ch04/ch04-01-what-is-ownership.html#variables-and-data-interacting-with-clone">“Variables and Data Interacting with
|
||
Clone”</a><!-- ignore --> section in
|
||
Chapter 4 for more information on <code>Clone</code>.</p>
|
||
<p>Deriving <code>Clone</code> implements the <code>clone</code> method, which when implemented for the
|
||
whole type, calls <code>clone</code> on each of the parts of the type. This means all the
|
||
fields or values in the type must also implement <code>Clone</code> to derive <code>Clone</code>.</p>
|
||
<p>An example of when <code>Clone</code> is required is when calling the <code>to_vec</code> method on a
|
||
slice. The slice doesn’t own the type instances it contains, but the vector
|
||
returned from <code>to_vec</code> will need to own its instances, so <code>to_vec</code> calls
|
||
<code>clone</code> on each item. Thus, the type stored in the slice must implement <code>Clone</code>.</p>
|
||
<p>The <code>Copy</code> trait allows you to duplicate a value by only copying bits stored on
|
||
the stack; no arbitrary code is necessary. See the <a href="../ch04/ch04-01-what-is-ownership.html#stack-only-data-copy">“Stack-Only Data:
|
||
Copy”</a><!-- ignore --> section in Chapter 4 for more
|
||
information on <code>Copy</code>.</p>
|
||
<p>The <code>Copy</code> 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.</p>
|
||
<p>You can derive <code>Copy</code> on any type whose parts all implement <code>Copy</code>. A type that
|
||
implements <code>Copy</code> must also implement <code>Clone</code> because a type that implements
|
||
<code>Copy</code> has a trivial implementation of <code>Clone</code> that performs the same task as
|
||
<code>Copy</code>.</p>
|
||
<p>The <code>Copy</code> trait is rarely required; types that implement <code>Copy</code> have
|
||
optimizations available, meaning you don’t have to call <code>clone</code>, which makes
|
||
the code more concise.</p>
|
||
<p>Everything possible with <code>Copy</code> you can also accomplish with <code>Clone</code>, but the
|
||
code might be slower or have to use <code>clone</code> in places.</p>
|
||
<h3 id="hash-for-mapping-a-value-to-a-value-of-fixed-size"><a class="header" href="#hash-for-mapping-a-value-to-a-value-of-fixed-size"><code>Hash</code> for Mapping a Value to a Value of Fixed Size</a></h3>
|
||
<p>The <code>Hash</code> 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
|
||
<code>Hash</code> implements the <code>hash</code> method. The derived implementation of the <code>hash</code>
|
||
method combines the result of calling <code>hash</code> on each of the parts of the type,
|
||
meaning all fields or values must also implement <code>Hash</code> to derive <code>Hash</code>.</p>
|
||
<p>An example of when <code>Hash</code> is required is in storing keys in a <code>HashMap<K, V></code>
|
||
to store data efficiently.</p>
|
||
<h3 id="default-for-default-values"><a class="header" href="#default-for-default-values"><code>Default</code> for Default Values</a></h3>
|
||
<p>The <code>Default</code> trait allows you to create a default value for a type. Deriving
|
||
<code>Default</code> implements the <code>default</code> function. The derived implementation of the
|
||
<code>default</code> function calls the <code>default</code> function on each part of the type,
|
||
meaning all fields or values in the type must also implement <code>Default</code> to
|
||
derive <code>Default</code>.</p>
|
||
<p>The <code>Default::default</code> function is commonly used in combination with the struct
|
||
update syntax discussed in the <a href="../ch05/ch05-01-defining-structs.html#creating-instances-from-other-instances-with-struct-update-syntax">“Creating Instances from Other Instances with
|
||
Struct Update
|
||
Syntax”</a><!--
|
||
ignore --> section in Chapter 5. 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
|
||
<code>..Default::default()</code>.</p>
|
||
<p>The <code>Default</code> trait is required when you use the method <code>unwrap_or_default</code> on
|
||
<code>Option<T></code> instances, for example. If the <code>Option<T></code> is <code>None</code>, the method
|
||
<code>unwrap_or_default</code> will return the result of <code>Default::default</code> for the type
|
||
<code>T</code> stored in the <code>Option<T></code>.</p>
|
||
</body>
|
||
</html>
|