Sophie

Sophie

distrib > Mageia > 6 > armv7hl > media > core-updates > by-pkgid > 564935689ab5527f955e5449ded02799 > files > 308

rust-doc-1.19.0-1.mga6.armv7hl.rpm

<!DOCTYPE HTML>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Advanced Traits - The Rust Programming Language</title>
        <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <base href="">

        <link rel="stylesheet" href="book.css">
        <link href='https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/css'>

        <link rel="shortcut icon" href="favicon.png">

        <!-- Font Awesome -->
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">

        <link rel="stylesheet" href="highlight.css">
        <link rel="stylesheet" href="tomorrow-night.css">
        <style>
            .page-wrapper.has-warning > .nav-chapters {
              /* add height for warning content & margin */
              top: 120px;
            }

            p.warning {
                background-color: rgb(242, 222, 222);
                border-bottom-color: rgb(238, 211, 215);
                border-bottom-left-radius: 4px;
                border-bottom-right-radius: 4px;
                border-bottom-style: solid;
                border-bottom-width: 0.666667px;
                border-image-outset: 0 0 0 0;
                border-image-repeat: stretch stretch;
                border-image-slice: 100% 100% 100% 100%;
                border-image-source: none;
                border-image-width: 1 1 1 1;
                border-left-color: rgb(238, 211, 215);
                border-left-style: solid;
                border-left-width: 0.666667px;
                border-right-color: rgb(238, 211, 215);
                border-right-style: solid;
                border-right-width: 0.666667px;
                border-top-color: rgb(238, 211, 215);
                border-top-left-radius: 4px;
                border-top-right-radius: 4px;
                border-top-style: solid;
                border-top-width: 0.666667px;
                color: rgb(185, 74, 72);
                margin-bottom: 0px;
                margin-left: 0px;
                margin-right: 0px;
                margin-top: 30px;
                padding-bottom: 8px;
                padding-left: 14px;
                padding-right: 35px;
                padding-top: 8px;
            }
            p.warning strong {
                color: rgb(185, 74, 72)
            }
            p.warning a {
                color: rgb(0, 136, 204)
            }
        </style>

        <!-- MathJax -->
        <script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>

        <!-- Fetch JQuery from CDN but have a local fallback -->
        <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
        <script>
            if (typeof jQuery == 'undefined') {
                document.write(unescape("%3Cscript src='jquery.js'%3E%3C/script%3E"));
            }
        </script>
    </head>
    <body class="light">
        <!-- Set the theme before any content is loaded, prevents flash -->
        <script type="text/javascript">
            var theme = localStorage.getItem('theme');
            if (theme == null) { theme = 'light'; }
            $('body').removeClass().addClass(theme);
        </script>

        <!-- Hide / unhide sidebar before it is displayed -->
        <script type="text/javascript">
            var sidebar = localStorage.getItem('sidebar');
            if (sidebar === "hidden") { $("html").addClass("sidebar-hidden") }
            else if (sidebar === "visible") { $("html").addClass("sidebar-visible") }
        </script>

        <div id="sidebar" class="sidebar">
            <ul class="chapter"><li><a href="ch01-00-introduction.html"><strong>1.</strong> Introduction</a></li><li><ul class="section"><li><a href="ch01-01-installation.html"><strong>1.1.</strong> Installation</a></li><li><a href="ch01-02-hello-world.html"><strong>1.2.</strong> Hello, World!</a></li></ul></li><li><a href="ch02-00-guessing-game-tutorial.html"><strong>2.</strong> Guessing Game Tutorial</a></li><li><a href="ch03-00-common-programming-concepts.html"><strong>3.</strong> Common Programming Concepts</a></li><li><ul class="section"><li><a href="ch03-01-variables-and-mutability.html"><strong>3.1.</strong> Variables and Mutability</a></li><li><a href="ch03-02-data-types.html"><strong>3.2.</strong> Data Types</a></li><li><a href="ch03-03-how-functions-work.html"><strong>3.3.</strong> How Functions Work</a></li><li><a href="ch03-04-comments.html"><strong>3.4.</strong> Comments</a></li><li><a href="ch03-05-control-flow.html"><strong>3.5.</strong> Control Flow</a></li></ul></li><li><a href="ch04-00-understanding-ownership.html"><strong>4.</strong> Understanding Ownership</a></li><li><ul class="section"><li><a href="ch04-01-what-is-ownership.html"><strong>4.1.</strong> What is Ownership?</a></li><li><a href="ch04-02-references-and-borrowing.html"><strong>4.2.</strong> References &amp; Borrowing</a></li><li><a href="ch04-03-slices.html"><strong>4.3.</strong> Slices</a></li></ul></li><li><a href="ch05-00-structs.html"><strong>5.</strong> Using Structs to Structure Related Data</a></li><li><ul class="section"><li><a href="ch05-01-defining-structs.html"><strong>5.1.</strong> Defining and Instantiating Structs</a></li><li><a href="ch05-02-example-structs.html"><strong>5.2.</strong> An Example Program Using Structs</a></li><li><a href="ch05-03-method-syntax.html"><strong>5.3.</strong> Method Syntax</a></li></ul></li><li><a href="ch06-00-enums.html"><strong>6.</strong> Enums and Pattern Matching</a></li><li><ul class="section"><li><a href="ch06-01-defining-an-enum.html"><strong>6.1.</strong> Defining an Enum</a></li><li><a href="ch06-02-match.html"><strong>6.2.</strong> The <code>match</code> Control Flow Operator</a></li><li><a href="ch06-03-if-let.html"><strong>6.3.</strong> Concise Control Flow with <code>if let</code></a></li></ul></li><li><a href="ch07-00-modules.html"><strong>7.</strong> Modules</a></li><li><ul class="section"><li><a href="ch07-01-mod-and-the-filesystem.html"><strong>7.1.</strong> <code>mod</code> and the Filesystem</a></li><li><a href="ch07-02-controlling-visibility-with-pub.html"><strong>7.2.</strong> Controlling Visibility with <code>pub</code></a></li><li><a href="ch07-03-importing-names-with-use.html"><strong>7.3.</strong> Importing Names with <code>use</code></a></li></ul></li><li><a href="ch08-00-common-collections.html"><strong>8.</strong> Common Collections</a></li><li><ul class="section"><li><a href="ch08-01-vectors.html"><strong>8.1.</strong> Vectors</a></li><li><a href="ch08-02-strings.html"><strong>8.2.</strong> Strings</a></li><li><a href="ch08-03-hash-maps.html"><strong>8.3.</strong> Hash Maps</a></li></ul></li><li><a href="ch09-00-error-handling.html"><strong>9.</strong> Error Handling</a></li><li><ul class="section"><li><a href="ch09-01-unrecoverable-errors-with-panic.html"><strong>9.1.</strong> Unrecoverable Errors with <code>panic!</code></a></li><li><a href="ch09-02-recoverable-errors-with-result.html"><strong>9.2.</strong> Recoverable Errors with <code>Result</code></a></li><li><a href="ch09-03-to-panic-or-not-to-panic.html"><strong>9.3.</strong> To <code>panic!</code> or Not To <code>panic!</code></a></li></ul></li><li><a href="ch10-00-generics.html"><strong>10.</strong> Generic Types, Traits, and Lifetimes</a></li><li><ul class="section"><li><a href="ch10-01-syntax.html"><strong>10.1.</strong> Generic Data Types</a></li><li><a href="ch10-02-traits.html"><strong>10.2.</strong> Traits: Defining Shared Behavior</a></li><li><a href="ch10-03-lifetime-syntax.html"><strong>10.3.</strong> Validating References with Lifetimes</a></li></ul></li><li><a href="ch11-00-testing.html"><strong>11.</strong> Testing</a></li><li><ul class="section"><li><a href="ch11-01-writing-tests.html"><strong>11.1.</strong> Writing tests</a></li><li><a href="ch11-02-running-tests.html"><strong>11.2.</strong> Running tests</a></li><li><a href="ch11-03-test-organization.html"><strong>11.3.</strong> Test Organization</a></li></ul></li><li><a href="ch12-00-an-io-project.html"><strong>12.</strong> An I/O Project</a></li><li><ul class="section"><li><a href="ch12-01-accepting-command-line-arguments.html"><strong>12.1.</strong> Accepting Command Line Arguments</a></li><li><a href="ch12-02-reading-a-file.html"><strong>12.2.</strong> Reading a File</a></li><li><a href="ch12-03-improving-error-handling-and-modularity.html"><strong>12.3.</strong> Improving Error Handling and Modularity</a></li><li><a href="ch12-04-testing-the-librarys-functionality.html"><strong>12.4.</strong> Testing the Library's Functionality</a></li><li><a href="ch12-05-working-with-environment-variables.html"><strong>12.5.</strong> Working with Environment Variables</a></li><li><a href="ch12-06-writing-to-stderr-instead-of-stdout.html"><strong>12.6.</strong> Writing to <code>stderr</code> instead of <code>stdout</code></a></li></ul></li><li><a href="ch13-00-functional-features.html"><strong>13.</strong> Functional Language Features in Rust</a></li><li><ul class="section"><li><a href="ch13-01-closures.html"><strong>13.1.</strong> Closures</a></li><li><a href="ch13-02-iterators.html"><strong>13.2.</strong> Iterators</a></li><li><a href="ch13-03-improving-our-io-project.html"><strong>13.3.</strong> Improving our I/O Project</a></li><li><a href="ch13-04-performance.html"><strong>13.4.</strong> Performance</a></li></ul></li><li><a href="ch14-00-more-about-cargo.html"><strong>14.</strong> More about Cargo and Crates.io</a></li><li><ul class="section"><li><a href="ch14-01-release-profiles.html"><strong>14.1.</strong> Release Profiles</a></li><li><a href="ch14-02-publishing-to-crates-io.html"><strong>14.2.</strong> Publishing a Crate to Crates.io</a></li><li><a href="ch14-03-cargo-workspaces.html"><strong>14.3.</strong> Cargo Workspaces</a></li><li><a href="ch14-04-installing-binaries.html"><strong>14.4.</strong> Installing Binaries from Crates.io with <code>cargo install</code></a></li><li><a href="ch14-05-extending-cargo.html"><strong>14.5.</strong> Extending Cargo with Custom Commands</a></li></ul></li><li><a href="ch15-00-smart-pointers.html"><strong>15.</strong> Smart Pointers</a></li><li><ul class="section"><li><a href="ch15-01-box.html"><strong>15.1.</strong> <code>Box&lt;T&gt;</code> Points to Data on the Heap and Has a Known Size</a></li><li><a href="ch15-02-deref.html"><strong>15.2.</strong> The <code>Deref</code> Trait Allows Access to the Data Through a Reference</a></li><li><a href="ch15-03-drop.html"><strong>15.3.</strong> The <code>Drop</code> Trait Runs Code on Cleanup</a></li><li><a href="ch15-04-rc.html"><strong>15.4.</strong> <code>Rc&lt;T&gt;</code>, the Reference Counted Smart Pointer</a></li><li><a href="ch15-05-interior-mutability.html"><strong>15.5.</strong> <code>RefCell&lt;T&gt;</code> and the Interior Mutability Pattern</a></li><li><a href="ch15-06-reference-cycles.html"><strong>15.6.</strong> Creating Reference Cycles and Leaking Memory is Safe</a></li></ul></li><li><a href="ch16-00-concurrency.html"><strong>16.</strong> Fearless Concurrency</a></li><li><ul class="section"><li><a href="ch16-01-threads.html"><strong>16.1.</strong> Threads</a></li><li><a href="ch16-02-message-passing.html"><strong>16.2.</strong> Message Passing</a></li><li><a href="ch16-03-shared-state.html"><strong>16.3.</strong> Shared State</a></li><li><a href="ch16-04-extensible-concurrency-sync-and-send.html"><strong>16.4.</strong> Extensible Concurrency: <code>Sync</code> and <code>Send</code></a></li></ul></li><li><a href="ch17-00-oop.html"><strong>17.</strong> Is Rust an Object-Oriented Programming Language?</a></li><li><ul class="section"><li><a href="ch17-01-what-is-oo.html"><strong>17.1.</strong> What Does Object-Oriented Mean?</a></li><li><a href="ch17-02-trait-objects.html"><strong>17.2.</strong> Trait Objects for Using Values of Different Types</a></li><li><a href="ch17-03-oo-design-patterns.html"><strong>17.3.</strong> Object-Oriented Design Pattern Implementations</a></li></ul></li><li><a href="ch18-00-patterns.html"><strong>18.</strong> Patterns Match the Structure of Values</a></li><li><ul class="section"><li><a href="ch18-01-all-the-places-for-patterns.html"><strong>18.1.</strong> All the Places Patterns May be Used</a></li><li><a href="ch18-02-refutability.html"><strong>18.2.</strong> Refutability: Whether a Pattern Might Fail to Match</a></li><li><a href="ch18-03-pattern-syntax.html"><strong>18.3.</strong> All the Pattern Syntax</a></li></ul></li><li><a href="ch19-00-advanced-features.html"><strong>19.</strong> Advanced Features</a></li><li><ul class="section"><li><a href="ch19-01-unsafe-rust.html"><strong>19.1.</strong> Unsafe Rust</a></li><li><a href="ch19-02-advanced-lifetimes.html"><strong>19.2.</strong> Advanced Lifetimes</a></li><li><a href="ch19-03-advanced-traits.html" class="active"><strong>19.3.</strong> Advanced Traits</a></li><li><a href="ch19-04-advanced-types.html"><strong>19.4.</strong> Advanced Types</a></li><li><a href="ch19-05-advanced-functions-and-closures.html"><strong>19.5.</strong> Advanced Functions &amp; Closures</a></li></ul></li><li><a href="ch20-00-final-project-a-web-server.html"><strong>20.</strong> Final Project: Building a Multithreaded Web Server</a></li><li><ul class="section"><li><a href="ch20-01-single-threaded.html"><strong>20.1.</strong> A Single Threaded Web Server</a></li><li><a href="ch20-02-slow-requests.html"><strong>20.2.</strong> How Slow Requests Affect Throughput</a></li><li><a href="ch20-03-designing-the-interface.html"><strong>20.3.</strong> Designing the Thread Pool Interface</a></li><li><a href="ch20-04-storing-threads.html"><strong>20.4.</strong> Creating the Thread Pool and Storing Threads</a></li><li><a href="ch20-05-sending-requests-via-channels.html"><strong>20.5.</strong> Sending Requests to Threads Via Channels</a></li><li><a href="ch20-06-graceful-shutdown-and-cleanup.html"><strong>20.6.</strong> Graceful Shutdown and Cleanup</a></li></ul></li><li><a href="appendix-00.html"><strong>21.</strong> Appendix</a></li><li><ul class="section"><li><a href="appendix-01-keywords.html"><strong>21.1.</strong> A - Keywords</a></li><li><a href="appendix-02-operators.html"><strong>21.2.</strong> B - Operators</a></li><li><strong>21.3.</strong> C - Derivable Traits</li><li><strong>21.4.</strong> D - Nightly Rust</li><li><strong>21.5.</strong> E - Macros</li><li><strong>21.6.</strong> F - Translations</li><li><a href="appendix-07-newest-features.html"><strong>21.7.</strong> G - Newest Features</a></li></ul></li></ul>
        </div>

        <div id="page-wrapper" class="page-wrapper has-warning">

            <div class="page">
                <header><p class="warning">You are reading a <strong>draft</strong> of the next edition of TRPL. For more, go <a href="../index.html">here</a>.</p></header>
                <div id="menu-bar" class="menu-bar">
                    <div class="left-buttons">
                        <i id="sidebar-toggle" class="fa fa-bars"></i>
                        <i id="theme-toggle" class="fa fa-paint-brush"></i>
                    </div>

                    <h1 class="menu-title">The Rust Programming Language</h1>

                    <div class="right-buttons">
                        <i id="print-button" class="fa fa-print" title="Print this book"></i>
                    </div>
                </div>


                <div id="content" class="content">
                    <a class="header" href="ch19-03-advanced-traits.html#advanced-traits" id="advanced-traits"><h2>Advanced Traits</h2></a>
<p>We covered traits in Chapter 10, but like lifetimes, we didn't get to all the
details. Now that we know more Rust, we can get into the nitty-gritty.</p>
<a class="header" href="ch19-03-advanced-traits.html#associated-types" id="associated-types"><h3>Associated Types</h3></a>
<p><em>Associated types</em> are a way of associating a type placeholder with a trait
such that the trait method definitions can use these placeholder types in their
signatures. The implementer of a trait will specify the concrete type to be
used in this type's place for the particular implementation.</p>
<p>We've described most of the things in this chapter as being very rare.
Associated types are somewhere in the middle; they're more rare than the rest
of the book, but more common than many of the things in this chapter.</p>
<p>An example of a trait with an associated type is the <code>Iterator</code> trait provided
by the standard library. It has an associated type named <code>Item</code> that stands in
for the type of the values that we're iterating over. We mentioned in Chapter
13 that the definition of the <code>Iterator</code> trait is as shown in Listing 19-20:</p>
<pre><pre class="playpen"><code class="language-rust"># #![allow(unused_variables)]
#fn main() {
pub trait Iterator {
    type Item;
    fn next(&amp;mut self) -&gt; Option&lt;Self::Item&gt;;
}

#}</code></pre></pre>
<p><span class="caption">Listing 19-20: The definition of the <code>Iterator</code> trait
that has an associated type <code>Item</code></span></p>
<p>This says that the <code>Iterator</code> trait has an associated type named <code>Item</code>. <code>Item</code>
is a placeholder type, and the return value of the <code>next</code> method will return
values of type <code>Option&lt;Self::Item&gt;</code>. Implementers of this trait will specify
the concrete type for <code>Item</code>, and the <code>next</code> method will return an <code>Option</code>
containing a value of whatever type the implementer has specified.</p>
<a class="header" href="ch19-03-advanced-traits.html#associated-types-versus-generics" id="associated-types-versus-generics"><h4>Associated Types Versus Generics</h4></a>
<p>When we implemented the <code>Iterator</code> trait on the <code>Counter</code> struct in Listing
13-6, we specified that the <code>Item</code> type was <code>u32</code>:</p>
<pre><code class="language-rust ignore">impl Iterator for Counter {
    type Item = u32;

    fn next(&amp;mut self) -&gt; Option&lt;Self::Item&gt; {
</code></pre>
<p>This feels similar to generics. So why isn't the <code>Iterator</code> trait defined as
shown in Listing 19-21?</p>
<pre><pre class="playpen"><code class="language-rust"># #![allow(unused_variables)]
#fn main() {
pub trait Iterator&lt;T&gt; {
    fn next(&amp;mut self) -&gt; Option&lt;T&gt;;
}

#}</code></pre></pre>
<p><span class="caption">Listing 19-21: A hypothetical definition of the
<code>Iterator</code> trait using generics</span></p>
<p>The difference is that with the definition in Listing 19-21, we could also
implement <code>Iterator&lt;String&gt; for Counter</code>, or any other type as well, so that
we'd have multiple implementations of <code>Iterator</code> for <code>Counter</code>. In other words,
when a trait has a generic parameter, we can implement that trait for a type
multiple times, changing the generic type parameters' concrete types each time.
Then when we use the <code>next</code> method on <code>Counter</code>, we'd have to provide type
annotations to indicate which implementation of <code>Iterator</code> we wanted to use.</p>
<p>With associated types, we can't implement a trait on a type multiple times.
Using the actual definition of <code>Iterator</code> from Listing 19-20, we can only
choose once what the type of <code>Item</code> will be, since there can only be one <code>impl Iterator for Counter</code>. We don't have to specify that we want an iterator of
<code>u32</code> values everywhere that we call <code>next</code> on <code>Counter</code>.</p>
<p>The benefit of not having to specify generic type parameters when a trait uses
associated types shows up in another way as well. Consider the two traits
defined in Listing 19-22. Both are defining a trait having to do with a graph
structure that contains nodes of some type and edges of some type. <code>GGraph</code> is
defined using generics, and <code>AGraph</code> is defined using associated types:</p>
<pre><pre class="playpen"><code class="language-rust"># #![allow(unused_variables)]
#fn main() {
trait GGraph&lt;Node, Edge&gt; {
    // methods would go here
}

trait AGraph {
    type Node;
    type Edge;

    // methods would go here
}

#}</code></pre></pre>
<p><span class="caption">Listing 19-22: Two graph trait definitions, <code>GGraph</code>
using generics and <code>AGraph</code> using associated types for <code>Node</code> and <code>Edge</code></span></p>
<p>Let's say we wanted to implement a function that computes the distance between
two nodes in any types that implement the graph trait. With the <code>GGraph</code> trait
defined using generics, our <code>distance</code> function signature would have to look
like Listing 19-23:</p>
<pre><pre class="playpen"><code class="language-rust"># #![allow(unused_variables)]
#fn main() {
# trait GGraph&lt;Node, Edge&gt; {}
#
fn distance&lt;N, E, G: GGraph&lt;N, E&gt;&gt;(graph: &amp;G, start: &amp;N, end: &amp;N) -&gt; u32 {
#     0
}

#}</code></pre></pre>
<p><span class="caption">Listing 19-23: The signature of a <code>distance</code> function
that uses the trait <code>GGraph</code> and has to specify all the generic
parameters</span></p>
<p>Our function would need to specify the generic type parameters <code>N</code>, <code>E</code>, and
<code>G</code>, where <code>G</code> is bound by the trait <code>GGraph</code> that has type <code>N</code> as its <code>Node</code>
type and type <code>E</code> as its <code>Edge</code> type. Even though <code>distance</code> doesn't need to
know the types of the edges, we're forced to declare an <code>E</code> parameter, because
we need to to use the <code>GGraph</code> trait and that requires specifying the type for
<code>Edge</code>.</p>
<p>Contrast with the definition of <code>distance</code> in Listing 19-24 that uses the
<code>AGraph</code> trait from Listing 19-22 with associated types:</p>
<pre><pre class="playpen"><code class="language-rust"># #![allow(unused_variables)]
#fn main() {
# trait AGraph {
#     type Node;
#     type Edge;
# }
#
fn distance&lt;G: AGraph&gt;(graph: &amp;G, start: &amp;G::Node, end: &amp;G::Node) -&gt; u32 {
#     0
}

#}</code></pre></pre>
<p><span class="caption">Listing 19-24: The signature of a <code>distance</code> function
that uses the trait <code>AGraph</code> and the associated type <code>Node</code></span></p>
<p>This is much cleaner. We only need to have one generic type parameter, <code>G</code>,
with the trait bound <code>AGraph</code>. Since <code>distance</code> doesn't use the <code>Edge</code> type at
all, it doesn't need to be specified anywhere. To use the <code>Node</code> type
associated with <code>AGraph</code>, we can specify <code>G::Node</code>.</p>
<a class="header" href="ch19-03-advanced-traits.html#trait-objects-with-associated-types" id="trait-objects-with-associated-types"><h4>Trait Objects with Associated Types</h4></a>
<p>You may have been wondering why we didn't use a trait object in the <code>distance</code>
functions in Listing 19-23 and Listing 19-24. The signature for the <code>distance</code>
function using the generic <code>GGraph</code> trait does get a bit more concise using a
trait object:</p>
<pre><pre class="playpen"><code class="language-rust"># #![allow(unused_variables)]
#fn main() {
# trait GGraph&lt;Node, Edge&gt; {}
#
fn distance&lt;N, E&gt;(graph: &amp;GGraph&lt;N, E&gt;, start: &amp;N, end: &amp;N) -&gt; u32 {
#     0
}

#}</code></pre></pre>
<p>This might be a more fair comparison to Listing 19-24. Specifying the <code>Edge</code>
type is still required, though, which means Listing 19-24 is still preferable
since we don't have to specify something we don't use.</p>
<p>It's not possible to change Listing 19-24 to use a trait object for the graph,
since then there would be no way to refer to the <code>AGraph</code> trait's associated
type.</p>
<p>It is possible in general to use trait objects of traits that have associated
types, though; Listing 19-25 shows a function named <code>traverse</code> that doesn't
need to use the trait's associated types in other arguments. We do, however,
have to specify the concrete types for the associated types in this case. Here,
we've chosen to accept types that implement the <code>AGraph</code> trait with the
concrete type of <code>usize</code> as their <code>Node</code> type and a tuple of two <code>usize</code> values
for their <code>Edge</code> type:</p>
<pre><pre class="playpen"><code class="language-rust"># #![allow(unused_variables)]
#fn main() {
# trait AGraph {
#     type Node;
#     type Edge;
# }
#
fn traverse(graph: &amp;AGraph&lt;Node=usize, Edge=(usize, usize)&gt;) {}

#}</code></pre></pre>
<p>While trait objects mean that we don't need to know the concrete type of the
<code>graph</code> parameter at compile time, we do need to constrain the use of the
<code>AGraph</code> trait in the <code>traverse</code> function by the concrete types of the
associated types. If we didn’t provide this constraint, Rust wouldn't be able
to figure out which <code>impl</code> to match this trait object to, because the
associated types can be part of the signatures of the methods that Rust needs
to look up in the vtable.</p>
<a class="header" href="ch19-03-advanced-traits.html#operator-overloading-and-default-type-parameters" id="operator-overloading-and-default-type-parameters"><h3>Operator Overloading and Default Type Parameters</h3></a>
<p>The <code>&lt;PlaceholderType=ConcreteType&gt;</code> syntax is used in another way as well: to
specify the default type for a generic type. A great example of a situation
where this is useful is operator overloading.</p>
<p>Rust does not allow you to create your own operators or overload arbitrary
operators, but the operations and corresponding traits listed in <code>std::ops</code> can
be overloaded by implementing the traits associated with the operator. For
example, Listing 19-25 shows how to overload the <code>+</code> operator by implementing
the <code>Add</code> trait on a <code>Point</code> struct so that we can add two <code>Point</code> instances
together:</p>
<p><span class="filename">Filename: src/main.rs</span></p>
<pre><pre class="playpen"><code class="language-rust">use std::ops::Add;

#[derive(Debug,PartialEq)]
struct Point {
    x: i32,
    y: i32,
}

impl Add for Point {
    type Output = Point;

    fn add(self, other: Point) -&gt; Point {
        Point {
            x: self.x + other.x,
            y: self.y + other.y,
        }
    }
}

fn main() {
    assert_eq!(Point { x: 1, y: 0 } + Point { x: 2, y: 3 },
               Point { x: 3, y: 3 });
}
</code></pre></pre>
<p><span class="caption">Listing 19-25: Implementing the <code>Add</code> trait to overload
the <code>+</code> operator for <code>Point</code> instances</span></p>
<p>We've implemented the <code>add</code> method to add the <code>x</code> values of two <code>Point</code>
instances together and the <code>y</code> values of two <code>Point</code> instances together to
create a new <code>Point</code>. The <code>Add</code> trait has an <code>Output</code> associated type that's
used to determine the type returned from <code>add</code>. result of the operation.</p>
<p>Let's look at the <code>Add</code> trait in a bit more detail. Here's its definition:</p>
<pre><pre class="playpen"><code class="language-rust"># #![allow(unused_variables)]
#fn main() {
trait Add&lt;RHS=Self&gt; {
    type Output;

    fn add(self, rhs: RHS) -&gt; Self::Output;
}

#}</code></pre></pre>
<p>This should look familiar; it's a trait with one method and an associated type.
The new part is the <code>RHS=Self</code> in the angle brackets: this syntax is called
<em>default type parameters</em>. <code>RHS</code> is a generic type parameter (short for &quot;right
hand side&quot;) that's used for the type of the <code>rhs</code> parameter in the <code>add</code>
method. If we don't specify a concrete type for <code>RHS</code> when we implement the
<code>Add</code> trait, the type of <code>RHS</code> will default to the type of <code>Self</code> (the type
that we're implementing <code>Add</code> on).</p>
<p>Let's look at another example of implementing the <code>Add</code> trait. Imagine we have
two structs holding values in different units, <code>Millimeters</code> and <code>Meters</code>. We
can implement <code>Add</code> for <code>Millimeters</code> in different ways as shown in Listing
19-26:</p>
<pre><pre class="playpen"><code class="language-rust"># #![allow(unused_variables)]
#fn main() {
use std::ops::Add;

struct Millimeters(u32);
struct Meters(u32);

impl Add for Millimeters {
    type Output = Millimeters;

    fn add(self, other: Millimeters) -&gt; Millimeters {
        Millimeters(self.0 + other.0)
    }
}

impl Add&lt;Meters&gt; for Millimeters {
    type Output = Millimeters;

    fn add(self, other: Meters) -&gt; Millimeters {
        Millimeters(self.0 + (other.0 * 1000))
    }
}

#}</code></pre></pre>
<p><span class="caption">Listing 19-26: Implementing the <code>Add</code> trait on
<code>Millimeters</code> to be able to add <code>Millimeters</code> to <code>Millimeters</code> and
<code>Millimeters</code> to <code>Meters</code></span></p>
<p>If we're adding <code>Millimeters</code> to other <code>Millimeters</code>, we don't need to
parameterize the <code>RHS</code> type for <code>Add</code> since the default <code>Self</code> type is what we
want. If we want to implement adding <code>Millimeters</code> and <code>Meters</code>, then we need
to say <code>impl Add&lt;Meters&gt;</code> to set the value of the <code>RHS</code> type parameter.</p>
<p>Default type parameters are used in two main ways:</p>
<ol>
<li>To extend a type without breaking existing code.</li>
<li>To allow customization in a way most users don't want.</li>
</ol>
<p>The <code>Add</code> trait is an example of the second purpose: most of the time, you're
adding two like types together. Using a default type parameter in the <code>Add</code>
trait definition makes it easier to implement the trait since you don't have to
specify the extra parameter most of the time. In other words, we've removed a
little bit of implementation boilerplate.</p>
<p>The first purpose is similar, but in reverse: since existing implementations of
a trait won't have specified a type parameter, if we want to add a type
parameter to an existing trait, giving it a default will let us extend the
functionality of the trait without breaking the existing implementation code.</p>
<a class="header" href="ch19-03-advanced-traits.html#fully-qualified-syntax-for-disambiguation" id="fully-qualified-syntax-for-disambiguation"><h3>Fully Qualified Syntax for Disambiguation</h3></a>
<p>Rust cannot prevent a trait from having a method with the same name as another
trait's method, nor can it prevent us from implementing both of these traits on
one type. We can also have a method implemented directly on the type with the
same name as well! In order to be able to call each of the methods with the
same name, then, we need to tell Rust which one we want to use. Consider the
code in Listing 19-27 where traits <code>Foo</code> and <code>Bar</code> both have method <code>f</code> and we
implement both traits on struct <code>Baz</code>, which also has a method named <code>f</code>:</p>
<p><span class="filename">Filename: src/main.rs</span></p>
<pre><pre class="playpen"><code class="language-rust">trait Foo {
    fn f(&amp;self);
}

trait Bar {
    fn f(&amp;self);
}

struct Baz;

impl Foo for Baz {
    fn f(&amp;self) { println!(&quot;Baz’s impl of Foo&quot;); }
}

impl Bar for Baz {
    fn f(&amp;self) { println!(&quot;Baz’s impl of Bar&quot;); }
}

impl Baz {
    fn f(&amp;self) { println!(&quot;Baz's impl&quot;); }
}

fn main() {
    let b = Baz;
    b.f();
}
</code></pre></pre>
<p><span class="caption">Listing 19-27: Implementing two traits that both have a
method with the same name as a method defined on the struct directly</span></p>
<p>For the implementation of the <code>f</code> method for the <code>Foo</code> trait on <code>Baz</code>, we're
printing out <code>Baz's impl of Foo</code>. For the implementation of the <code>f</code> method for
the <code>Bar</code> trait on <code>Baz</code>, we're printing out <code>Baz's impl of Bar</code>. The
implementation of <code>f</code> directly on <code>Baz</code> prints out <code>Baz's impl</code>. What should
happen when we call <code>b.f()</code>? In this case, Rust will always use the
implementation on <code>Baz</code> directly and will print out <code>Baz's impl</code>.</p>
<p>In order to be able to call the <code>f</code> method from <code>Foo</code> and the <code>f</code> method from
<code>Baz</code> rather than the implementation of <code>f</code> directly on <code>Baz</code>, we need to use
the <em>fully qualified syntax</em> for calling methods. It works like this: for any
method call like:</p>
<pre><code class="language-rust ignore">receiver.method(args);
</code></pre>
<p>We can fully qualify the method call like this:</p>
<pre><code class="language-rust ignore">&lt;Type as Trait&gt;::method(receiver, args);
</code></pre>
<p>So in order to disambiguate and be able to call all the <code>f</code> methods defined in
Listing 19-27, we specify that we want to treat the type <code>Baz</code> as each trait
within angle brackets, then use two colons, then call the <code>f</code> method and pass
the instance of <code>Baz</code> as the first argument. Listing 19-28 shows how to call
<code>f</code> from <code>Foo</code> and then <code>f</code> from <code>Bar</code> on <code>b</code>:</p>
<p><span class="filename">Filename: src/main.rs</span></p>
<pre><pre class="playpen"><code class="language-rust"># trait Foo {
#     fn f(&amp;self);
# }
# trait Bar {
#     fn f(&amp;self);
# }
# struct Baz;
# impl Foo for Baz {
#     fn f(&amp;self) { println!(&quot;Baz’s impl of Foo&quot;); }
# }
# impl Bar for Baz {
#     fn f(&amp;self) { println!(&quot;Baz’s impl of Bar&quot;); }
# }
# impl Baz {
#     fn f(&amp;self) { println!(&quot;Baz's impl&quot;); }
# }
#
fn main() {
    let b = Baz;
    b.f();
    &lt;Baz as Foo&gt;::f(&amp;b);
    &lt;Baz as Bar&gt;::f(&amp;b);
}
</code></pre></pre>
<p><span class="caption">Listing 19-28: Using fully qualified syntax to call the
<code>f</code> methods defined as part of the <code>Foo</code> and <code>Bar</code> traits</span></p>
<p>This will print:</p>
<pre><code class="language-text">Baz's impl
Baz’s impl of Foo
Baz’s impl of Bar
</code></pre>
<p>We only need the <code>Type as</code> part if it's ambiguous, and we only need the <code>&lt;&gt;</code>
part if we need the <code>Type as</code> part. So if we only had the <code>f</code> method directly
on <code>Baz</code> and the <code>Foo</code> trait implemented on <code>Baz</code> in scope, we could call the
<code>f</code> method in <code>Foo</code> by using <code>Foo::f(&amp;b)</code> since we wouldn't have to
disambiguate from the <code>Bar</code> trait.</p>
<p>We could also have called the <code>f</code> defined directly on <code>Baz</code> by using
<code>Baz::f(&amp;b)</code>, but since that definition of <code>f</code> is the one that gets used by
default when we call <code>b.f()</code>, it's not required to fully specify that
implementation if that's what we want to call.</p>
<a class="header" href="ch19-03-advanced-traits.html#supertraits-to-use-one-traits-functionality-within-another-trait" id="supertraits-to-use-one-traits-functionality-within-another-trait"><h3>Supertraits to Use One Trait's Functionality Within Another Trait</h3></a>
<p>Sometimes, we may want a trait to be able to rely on another trait also being
implemented wherever our trait is implemented, so that our trait can use the
other trait's functionality. The required trait is a <em>supertrait</em> of the trait
we're implementing.</p>
<p>For example, let's say we want to make an <code>OutlinePrint</code> trait with an
<code>outline_print</code> method that will print out a value outlined in asterisks. That
is, if our <code>Point</code> struct implements <code>Display</code> to result in <code>(x, y)</code>, calling
<code>outline_print</code> on a <code>Point</code> instance that has 1 for <code>x</code> and 3 for <code>y</code> would
look like:</p>
<pre><code class="language-text">**********
*        *
* (1, 3) *
*        *
**********
</code></pre>
<p>In the implementation of <code>outline_print</code>, since we want to be able to use the
<code>Display</code> trait's functionality, we need to be able to say that the
<code>OutlinePrint</code> trait will only work for types that also implement <code>Display</code> and
provide the functionality that <code>OutlinePrint</code> needs. We can do that in the
trait definition by specifying <code>OutlinePrint: Display</code>. It's like adding a
trait bound to the trait. Listing 19-29 shows an implementation of the
<code>OutlinePrint</code> trait:</p>
<pre><pre class="playpen"><code class="language-rust"># #![allow(unused_variables)]
#fn main() {
use std::fmt::Display;

trait OutlinePrint: Display {
    fn outline_print(&amp;self) {
        let output = self.to_string();
        let len = output.len();
        println!(&quot;{}&quot;, &quot;*&quot;.repeat(len + 4));
        println!(&quot;*{}*&quot;, &quot; &quot;.repeat(len + 2));
        println!(&quot;* {} *&quot;, output);
        println!(&quot;*{}*&quot;, &quot; &quot;.repeat(len + 2));
        println!(&quot;{}&quot;, &quot;*&quot;.repeat(len + 4));
    }
}

#}</code></pre></pre>
<p><span class="caption">Listing 19-29: Implementing the <code>OutlinePrint</code> trait that
requires the functionality from <code>Display</code></span></p>
<p>Because we've specified that <code>OutlinePrint</code> requires the <code>Display</code> trait, we
can use <code>to_string</code> in <code>outline_print</code> (<code>to_string</code> is automatically
implemented for any type that implements <code>Display</code>). If we hadn't added the <code>: Display</code> after the trait name and we tried to use <code>to_string</code> in
<code>outline_print</code>, we'd get an error that no method named <code>to_string</code> was found
for the type <code>&amp;Self</code> in the current scope.</p>
<p>If we try to implement <code>OutlinePrint</code> on a type that doesn't implement
<code>Display</code>, such as the <code>Point</code> struct:</p>
<pre><pre class="playpen"><code class="language-rust"># #![allow(unused_variables)]
#fn main() {
# trait OutlinePrint {}
struct Point {
    x: i32,
    y: i32,
}

impl OutlinePrint for Point {}

#}</code></pre></pre>
<p>We'll get an error that <code>Display</code> isn't implemented and that <code>Display</code> is
required by <code>OutlinePrint</code>:</p>
<pre><code class="language-text">error[E0277]: the trait bound `Point: std::fmt::Display` is not satisfied
  --&gt; src/main.rs:20:6
   |
20 | impl OutlinePrint for Point {}
   |      ^^^^^^^^^^^^ the trait `std::fmt::Display` is not implemented for
   `Point`
   |
   = note: `Point` cannot be formatted with the default formatter; try using
   `:?` instead if you are using a format string
   = note: required by `OutlinePrint`
</code></pre>
<p>Once we implement <code>Display</code> on <code>Point</code> and satisfy the constraint that
<code>OutlinePrint</code> requires, like so:</p>
<pre><pre class="playpen"><code class="language-rust"># #![allow(unused_variables)]
#fn main() {
# struct Point {
#     x: i32,
#     y: i32,
# }
#
use std::fmt;

impl fmt::Display for Point {
    fn fmt(&amp;self, f: &amp;mut fmt::Formatter) -&gt; fmt::Result {
        write!(f, &quot;({}, {})&quot;, self.x, self.y)
    }
}

#}</code></pre></pre>
<p>then implementing the <code>OutlinePrint</code> trait on <code>Point</code> will compile successfully
and we can call <code>outline_print</code> on a <code>Point</code> instance to display it within an
outline of asterisks.</p>
<a class="header" href="ch19-03-advanced-traits.html#the-newtype-pattern-to-implement-external-traits-on-external-types" id="the-newtype-pattern-to-implement-external-traits-on-external-types"><h3>The Newtype Pattern to Implement External Traits on External Types</h3></a>
<p>In Chapter 10, we mentioned the orphan rule, which says we're allowed to
implement a trait on a type as long as either the trait or the type are local
to our crate. One way to get around this restriction is to use the <em>newtype
pattern</em>, which involves creating a new type using a tuple struct with one
field as a thin wrapper around the type we want to implement a trait for. Then
the wrapper type is local to our crate, and we can implement the trait on the
wrapper. &quot;Newtype&quot; is a term originating from the Haskell programming language.
There's no runtime performance penalty for using this pattern. The wrapper type
is elided at compile time.</p>
<p>For example, if we wanted to implement <code>Display</code> on <code>Vec</code>, we can make a
<code>Wrapper</code> struct that holds an instance of <code>Vec</code>. Then we can implement
<code>Display</code> on <code>Wrapper</code> and use the <code>Vec</code> value as shown in Listing 19-30:</p>
<p><span class="filename">Filename: src/main.rs</span></p>
<pre><pre class="playpen"><code class="language-rust">use std::fmt;

struct Wrapper(Vec&lt;String&gt;);

impl fmt::Display for Wrapper {
    fn fmt(&amp;self, f: &amp;mut fmt::Formatter) -&gt; fmt::Result {
        write!(f, &quot;[{}]&quot;, self.0.join(&quot;, &quot;))
    }
}

fn main() {
    let w = Wrapper(vec![String::from(&quot;hello&quot;), String::from(&quot;world&quot;)]);
    println!(&quot;w = {}&quot;, w);
}
</code></pre></pre>
<p><span class="caption">Listing 19-30: Creating a <code>Wrapper</code> type around
<code>Vec&lt;String&gt;</code> to be able to implement <code>Display</code></span></p>
<p>The implementation of <code>Display</code> uses <code>self.0</code> to access the inner <code>Vec</code>, and
then we can use the functionality of the <code>Display</code> type on <code>Wrapper</code>.</p>
<p>The downside is that since <code>Wrapper</code> is a new type, it doesn't have the methods
of the value it's holding; we'd have to implement all the methods of <code>Vec</code> like
<code>push</code>, <code>pop</code>, and all the rest directly on <code>Wrapper</code> to delegate to <code>self.0</code>
in order to be able to treat <code>Wrapper</code> exactly like a <code>Vec</code>. If we wanted the
new type to have every single method that the inner type has, implementing the
<code>Deref</code> trait that we discussed in Chapter 15 on the wrapper to return the
inner type can be a solution. If we don't want the wrapper type to have all the
methods of the inner type, in order to restrict the wrapper type's behavior for
example, we'd have to implement just the methods we do want ourselves.</p>
<p>That's how the newtype pattern is used in relation to traits; it's also a
useful pattern without having traits involved. Let's switch focus now to talk
about some advanced ways to interact with Rust's type system.</p>

                </div>

                <!-- Mobile navigation buttons -->
                
                    <a href="ch19-02-advanced-lifetimes.html" class="mobile-nav-chapters previous">
                        <i class="fa fa-angle-left"></i>
                    </a>
                

                
                    <a href="ch19-04-advanced-types.html" class="mobile-nav-chapters next">
                        <i class="fa fa-angle-right"></i>
                    </a>
                

            </div>

            
                <a href="ch19-02-advanced-lifetimes.html" class="nav-chapters previous" title="You can navigate through the chapters using the arrow keys">
                    <i class="fa fa-angle-left"></i>
                </a>
            

            
                <a href="ch19-04-advanced-types.html" class="nav-chapters next" title="You can navigate through the chapters using the arrow keys">
                    <i class="fa fa-angle-right"></i>
                </a>
            

        </div>


        <!-- Local fallback for Font Awesome -->
        <script>
            if ($(".fa").css("font-family") !== "FontAwesome") {
                $('<link rel="stylesheet" type="text/css" href="_FontAwesome/css/font-awesome.css">').prependTo('head');
            }
        </script>

        <!-- Livereload script (if served using the cli tool) -->
        

        <script src="highlight.js"></script>
        <script src="book.js"></script>
    </body>
</html>