You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
easy_rust/Chapter_43.html

349 lines
25 KiB
HTML

<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title> Type aliases - Easy Rust</title>
<!-- Custom HTML head -->
<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">
<meta name="theme-color" content="#ffffff" />
<link rel="icon" href="favicon.svg">
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
</head>
<body>
<!-- Provide site root to javascript -->
<script type="text/javascript">
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded "><a href="Chapter_0.html"><strong aria-hidden="true">1.</strong> Updates</a></li><li class="chapter-item expanded "><a href="Chapter_1.html"><strong aria-hidden="true">2.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="Chapter_2.html"><strong aria-hidden="true">3.</strong> Who am I?</a></li><li class="chapter-item expanded "><a href="Chapter_3.html"><strong aria-hidden="true">4.</strong> Writing Rust in Easy English</a></li><li class="chapter-item expanded "><a href="Chapter_4.html"><strong aria-hidden="true">5.</strong> Rust Playground</a></li><li class="chapter-item expanded "><a href="Chapter_5.html"><strong aria-hidden="true">6.</strong> 🚧 and ⚠️</a></li><li class="chapter-item expanded "><a href="Chapter_6.html"><strong aria-hidden="true">7.</strong> Comments</a></li><li class="chapter-item expanded "><a href="Chapter_7.html"><strong aria-hidden="true">8.</strong> Types</a></li><li class="chapter-item expanded "><a href="Chapter_8.html"><strong aria-hidden="true">9.</strong> Type inference</a></li><li class="chapter-item expanded "><a href="Chapter_9.html"><strong aria-hidden="true">10.</strong> Printing 'hello, world!'</a></li><li class="chapter-item expanded "><a href="Chapter_10.html"><strong aria-hidden="true">11.</strong> Display and debug</a></li><li class="chapter-item expanded "><a href="Chapter_11.html"><strong aria-hidden="true">12.</strong> Mutability (changing)</a></li><li class="chapter-item expanded "><a href="Chapter_12.html"><strong aria-hidden="true">13.</strong> The stack, the heap, and pointers</a></li><li class="chapter-item expanded "><a href="Chapter_13.html"><strong aria-hidden="true">14.</strong> More about printing</a></li><li class="chapter-item expanded "><a href="Chapter_14.html"><strong aria-hidden="true">15.</strong> Strings</a></li><li class="chapter-item expanded "><a href="Chapter_15.html"><strong aria-hidden="true">16.</strong> const and static</a></li><li class="chapter-item expanded "><a href="Chapter_16.html"><strong aria-hidden="true">17.</strong> More on references</a></li><li class="chapter-item expanded "><a href="Chapter_17.html"><strong aria-hidden="true">18.</strong> Mutable references</a></li><li class="chapter-item expanded "><a href="Chapter_18.html"><strong aria-hidden="true">19.</strong> Giving references to functions</a></li><li class="chapter-item expanded "><a href="Chapter_19.html"><strong aria-hidden="true">20.</strong> Copy types</a></li><li class="chapter-item expanded "><a href="Chapter_20.html"><strong aria-hidden="true">21.</strong> Collection types</a></li><li class="chapter-item expanded "><a href="Chapter_21.html"><strong aria-hidden="true">22.</strong> Vectors</a></li><li class="chapter-item expanded "><a href="Chapter_22.html"><strong aria-hidden="true">23.</strong> Tuples</a></li><li class="chapter-item expanded "><a href="Chapter_23.html"><strong aria-hidden="true">24.</strong> Control flow</a></li><li class="chapter-item expanded "><a href="Chapter_24.html"><strong aria-hidden="true">25.</strong> Structs</a></li><li class="chapter-item expanded "><a href="Chapter_25.html"><strong aria-hidden="true">26.</strong> Enums</a></li><li class="chapter-item expanded "><a href="Chapter_26.html"><strong aria-hidden="true">27.</strong> Loops</a></li><li class="chapter-item expanded "><a href="Chapter_27.html"><strong aria-hidden="true">28.</strong> Implementing structs and enums</a></li><li class="chapter-item expanded "><a href="Chapter_28.html"><strong aria-hidden="true">29.</strong> Destructuring</a></li><li class="chapter-item expanded "><a href="Chapter_29.html"><strong aria-hidden="true">30.</strong> References and the dot operator</a></li><li class="chapter-item expanded "><a href="Chapter_30.html"><strong aria-hidden="true">31.</strong> Generics</a></li><li class="chapter-item expanded "><a href="Chapter_31.html"><strong aria-hidden="true">32.</strong> Option and Result</a></li><li class="chapter-item expanded "><a href="Chapter_32.html"><strong aria-hidden="true">33.</strong> Other collections</a></li><li class="chapter-item expanded "><a href="Chapter_33.html"><strong aria-hidden="true">34.</strong> The ? operator</a></li><li class="chapter-item expanded "><a href="Chapter_34.html"><strong aria-hidden="true">35.</strong> Traits</a></li><li class="chapter-item expanded "><a href="Chapter_35.html"><strong aria-hidden="true">36.</strong> Chaining methods</a></li><li class="chapter-item expanded "><a href="Chapter_36.html"><strong aria-hidden="true">37.</strong> Iterators</a></li><li class="chapter-item expanded "><a href="Chapter_37.html"><strong aria-hidden="true">38.</strong> Closures</a></li><li class="chapter-item expanded "><a href="Chapter_38.html"><strong aria-hidden="true">39.</strong> The dbg! macro and .inspect</a></li><li class="chapter-item expanded "><a href="Chapter_39.html"><strong aria-hidden="true">40.</strong> Types of &amp;str</a></li><li class="chapter-item expanded "><a href="Chapter_40.html"><strong aria-hidden="true">41.</strong> Lifetimes</a></li><li class="chapter-item expanded "><a href="Chapter_41.html"><strong aria-hidden="true">42.</strong> Interior mutability</a></li><li class="chapter-item expanded "><a href="Chapter_42.html"><strong aria-hidden="true">43.</strong> Cow</a></li><li class="chapter-item expanded "><a href="Chapter_43.html" class="active"><strong aria-hidden="true">44.</strong> Type aliases</a></li><li class="chapter-item expanded "><a href="Chapter_44.html"><strong aria-hidden="true">45.</strong> The todo! macro</a></li><li class="chapter-item expanded "><a href="Chapter_45.html"><strong aria-hidden="true">46.</strong> Rc</a></li><li class="chapter-item expanded "><a href="Chapter_46.html"><strong aria-hidden="true">47.</strong> Multiple threads</a></li><li class="chapter-item expanded "><a href="Chapter_47.html"><strong aria-hidden="true">48.</strong> Closures in functions</a></li><li class="chapter-item expanded "><a href="Chapter_48.html"><strong aria-hidden="true">49.</strong> impl Trait</a></li><li class="chapter-item expanded "><a href="Chapter_49.html"><strong aria-hidden="true">50.</strong> Arc</a></li><li class="chapter-item expanded "><a href="Chapter_50.html"><strong aria-hidden="true">51.</strong> Channels</a></li><li class="chapter-item expanded "><a href="Chapter_51.html"><strong aria-hidden="true">52.</strong> Reading Rust documentation</a></li><li class="chapter-item expanded "><a href="Chapter_52.html"><strong aria-hidden="true">53.</strong> Attributes</a></li><li class="chapter-item expanded "><a href="Chapter_53.html"><strong aria-hidden="true">54.</strong> Box</a></li><li class="chapter-item expanded "><a href="Chapter_54.html"><strong aria-hidden="true">55.</strong> Box around traits</a></li><li class="chapter-item expanded "><a href="Chapter_55.html"><strong aria-hidden="true">56.</strong> Default and the builder pattern</a></li><li class="chapter-item expanded "><a href="Chapter_56.html"><strong aria-hidden="true">57.</strong> Deref and DerefMut</a></li><li class="chapter-item expanded "><a href="Chapter_57.html"><strong aria-hidden="true">58.</strong> Crates and modules</a></li><li class="chapter-item expanded "><a href="Chapter_58.html"><strong aria-hidden="true">59.</strong> Testing</a></li><li class="chapter-item expanded "><a href="Chapter_59.html"><strong aria-hidden="true">60.</strong> External crates</a></li><li class="chapter-item expanded "><a href="Chapter_60.html"><strong aria-hidden="true">61.</strong> A tour of the standard library</a></li><li class="chapter-item expanded "><a href="Chapter_61.html"><strong aria-hidden="true">62.</strong> Writing macros</a></li><li class="chapter-item expanded "><a href="Chapter_62.html"><strong aria-hidden="true">63.</strong> cargo</a></li><li class="chapter-item expanded "><a href="Chapter_63.html"><strong aria-hidden="true">64.</strong> Taking user input</a></li><li class="chapter-item expanded "><a href="Chapter_64.html"><strong aria-hidden="true">65.</strong> Using files</a></li><li class="chapter-item expanded "><a href="Chapter_65.html"><strong aria-hidden="true">66.</strong> cargo doc</a></li><li class="chapter-item expanded "><a href="Chapter_66.html"><strong aria-hidden="true">67.</strong> The end?</a></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky bordered">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Easy Rust</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script type="text/javascript">
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h2 id="type-aliases"><a class="header" href="#type-aliases">Type aliases</a></h2>
<p>A type alias means &quot;giving a new name to another type&quot;. Type aliases are very easy. Usually you use them when you have a very long type and don't want to write it every time. It is also good when you want to give a type a better name that is easy to remember. Here are two examples of type aliases.</p>
<p>Here is a type that is not difficult, but you want to make your code easier to understand for other people (or for you):</p>
<pre><pre class="playground"><code class="language-rust">type CharacterVec = Vec&lt;char&gt;;
fn main() {}
</code></pre></pre>
<p>Here's a type that is very difficult to read:</p>
<pre><pre class="playground"><code class="language-rust">// this return type is extremely long
fn returns&lt;'a&gt;(input: &amp;'a Vec&lt;char&gt;) -&gt; std::iter::Take&lt;std::iter::Skip&lt;std::slice::Iter&lt;'a, char&gt;&gt;&gt; {
input.iter().skip(4).take(5)
}
fn main() {}
</code></pre></pre>
<p>So you can change it to this:</p>
<pre><pre class="playground"><code class="language-rust">type SkipFourTakeFive&lt;'a&gt; = std::iter::Take&lt;std::iter::Skip&lt;std::slice::Iter&lt;'a, char&gt;&gt;&gt;;
fn returns&lt;'a&gt;(input: &amp;'a Vec&lt;char&gt;) -&gt; SkipFourTakeFive {
input.iter().skip(4).take(5)
}
fn main() {}
</code></pre></pre>
<p>Of course, you can also import items to make the type shorter:</p>
<pre><pre class="playground"><code class="language-rust">use std::iter::{Take, Skip};
use std::slice::Iter;
fn returns&lt;'a&gt;(input: &amp;'a Vec&lt;char&gt;) -&gt; Take&lt;Skip&lt;Iter&lt;'a, char&gt;&gt;&gt; {
input.iter().skip(4).take(5)
}
fn main() {}
</code></pre></pre>
<p>So you can decide what looks best in your code depending on what you like.</p>
<p>Note that this doesn't create an actual new type. It's just a name to use instead of an existing type. So if you write <code>type File = String;</code>, the compiler just sees a <code>String</code>. So this will print <code>true</code>:</p>
<pre><pre class="playground"><code class="language-rust">type File = String;
fn main() {
let my_file = File::from(&quot;I am file contents&quot;);
let my_string = String::from(&quot;I am file contents&quot;);
println!(&quot;{}&quot;, my_file == my_string);
}
</code></pre></pre>
<p>So what if you want an actual new type?</p>
<p>If you want a new file type that the compiler sees as a <code>File</code>, you can put it in a struct. (This is actually called the <code>newtype</code> idiom)</p>
<pre><pre class="playground"><code class="language-rust">struct File(String); // File is a wrapper around String
fn main() {
let my_file = File(String::from(&quot;I am file contents&quot;));
let my_string = String::from(&quot;I am file contents&quot;);
}
</code></pre></pre>
<p>Now this will not work, because they are two different types:</p>
<pre><pre class="playground"><code class="language-rust">struct File(String); // File is a wrapper around String
fn main() {
let my_file = File(String::from(&quot;I am file contents&quot;));
let my_string = String::from(&quot;I am file contents&quot;);
println!(&quot;{}&quot;, my_file == my_string); // ⚠️ cannot compare File with String
}
</code></pre></pre>
<p>If you want to compare the String inside, you can use my_file.0:</p>
<pre><pre class="playground"><code class="language-rust">struct File(String);
fn main() {
let my_file = File(String::from(&quot;I am file contents&quot;));
let my_string = String::from(&quot;I am file contents&quot;);
println!(&quot;{}&quot;, my_file.0 == my_string); // my_file.0 is a String, so this prints true
}
</code></pre></pre>
<p>And now this type doesn't have any traits, so you can implement them yourself. This is not too surprising:</p>
<pre><pre class="playground"><code class="language-rust">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>#[derive(Clone, Debug)]
struct File(String);
<span class="boring">}
</span></code></pre></pre>
<p>So when you use the <code>File</code> type here you can clone it and Debug print it, but it doesn't have the traits of String unless you use <code>.0</code> to get to the String inside it. But in other people's code you can only use <code>.0</code> if it's marked <code>pub</code> for public. And that's why these sorts of types use the <code>Deref</code> trait a lot. We will learn about both <code>pub</code> and <code>Deref</code> later.</p>
<h3 id="importing-and-renaming-inside-a-function"><a class="header" href="#importing-and-renaming-inside-a-function">Importing and renaming inside a function</a></h3>
<p>Usually you write <code>use</code> at the top of the program, like this:</p>
<pre><pre class="playground"><code class="language-rust">use std::cell::{Cell, RefCell};
fn main() {}
</code></pre></pre>
<p>But we saw that you can do this anywhere, especially in functions with enums that have long names. Here is an example.</p>
<pre><pre class="playground"><code class="language-rust">enum MapDirection {
North,
NorthEast,
East,
SouthEast,
South,
SouthWest,
West,
NorthWest,
}
fn main() {}
fn give_direction(direction: &amp;MapDirection) {
match direction {
MapDirection::North =&gt; println!(&quot;You are heading north.&quot;),
MapDirection::NorthEast =&gt; println!(&quot;You are heading northeast.&quot;),
// So much more left to type...
// ⚠️ because we didn't write every possible variant
}
}
</code></pre></pre>
<p>So now we will import MapDirection inside the function. That means that inside the function you can just write <code>North</code> and so on.</p>
<pre><pre class="playground"><code class="language-rust">enum MapDirection {
North,
NorthEast,
East,
SouthEast,
South,
SouthWest,
West,
NorthWest,
}
fn main() {}
fn give_direction(direction: &amp;MapDirection) {
use MapDirection::*; // Import everything in MapDirection
let m = &quot;You are heading&quot;;
match direction {
North =&gt; println!(&quot;{} north.&quot;, m),
NorthEast =&gt; println!(&quot;{} northeast.&quot;, m),
// This is a bit better
// ⚠️
}
}
</code></pre></pre>
<p>We've seen that <code>::*</code> means &quot;import everything after the ::&quot;. In our case, that means <code>North</code>, <code>NorthEast</code>...and all the way to <code>NorthWest</code>. When you import other people's code you can do that too, but if the code is very large you might have problems. What if it has some items that are the same as your code? So it's usually best to not use <code>::*</code> all the time unless you're sure. A lot of times you see a section called <code>prelude</code> in other people's code with all the main items you probably need. So then you will usually use it like this: <code>name::prelude::*</code>. We will talk about this more in the sections for <code>modules</code> and <code>crates</code>.</p>
<p>You can also use <code>as</code> to change the name. For example, maybe you are using someone else's code and you can't change the names in an enum:</p>
<pre><pre class="playground"><code class="language-rust">enum FileState {
CannotAccessFile,
FileOpenedAndReady,
NoSuchFileExists,
SimilarFileNameInNextDirectory,
}
fn main() {}
</code></pre></pre>
<p>So then you can 1) import everything and 2) change the names:</p>
<pre><pre class="playground"><code class="language-rust">enum FileState {
CannotAccessFile,
FileOpenedAndReady,
NoSuchFileExists,
SimilarFileNameInNextDirectory,
}
fn give_filestate(input: &amp;FileState) {
use FileState::{
CannotAccessFile as NoAccess,
FileOpenedAndReady as Good,
NoSuchFileExists as NoFile,
SimilarFileNameInNextDirectory as OtherDirectory
};
match input {
NoAccess =&gt; println!(&quot;Can't access file.&quot;),
Good =&gt; println!(&quot;Here is your file&quot;),
NoFile =&gt; println!(&quot;Sorry, there is no file by that name.&quot;),
OtherDirectory =&gt; println!(&quot;Please check the other directory.&quot;),
}
}
fn main() {}
</code></pre></pre>
<p>So now you can write <code>OtherDirectory</code> instead of <code>FileState::SimilarFileNameInNextDirectory</code>.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="Chapter_42.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="Chapter_44.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="Chapter_42.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="Chapter_44.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script type="text/javascript">
window.playground_copyable = true;
</script>
<script src="elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="mark.min.js" type="text/javascript" charset="utf-8"></script>
<script src="searcher.js" type="text/javascript" charset="utf-8"></script>
<script src="clipboard.min.js" type="text/javascript" charset="utf-8"></script>
<script src="highlight.js" type="text/javascript" charset="utf-8"></script>
<script src="book.js" type="text/javascript" charset="utf-8"></script>
<!-- Custom JS scripts -->
</body>
</html>