easy_rust/Chapter_33.html
2021-02-24 06:13:19 +00:00

495 lines
33 KiB
HTML

<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title> The ? operator - 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> Update</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" class="active"><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"><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" name="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="the--operator"><a class="header" href="#the--operator">The ? operator</a></h2>
<p>There is an even shorter way to deal with <code>Result</code> (and <code>Option</code>), shorter than <code>match</code> and even shorter than <code>if let</code>. It is called the &quot;question mark operator&quot;, and is just <code>?</code>. After a function that returns a result, you can add <code>?</code>. This will:</p>
<ul>
<li>return what is inside the <code>Result</code> if it is <code>Ok</code></li>
<li>pass the error back if it is <code>Err</code></li>
</ul>
<p>In other words, it does almost everything for you.</p>
<p>We can try this with <code>.parse()</code> again. We will write a function called <code>parse_str</code> that tries to turn a <code>&amp;str</code> into a <code>i32</code>. It looks like this:</p>
<pre><pre class="playground"><code class="language-rust">use std::num::ParseIntError;
fn parse_str(input: &amp;str) -&gt; Result&lt;i32, ParseIntError&gt; {
let parsed_number = input.parse::&lt;i32&gt;()?; // Here is the question mark
Ok(parsed_number)
}
fn main() {}
</code></pre></pre>
<p>This function takes a <code>&amp;str</code>. If it is <code>Ok</code>, it gives an <code>i32</code> wrapped in <code>Ok</code>. If it is an <code>Err</code>, it returns a <code>ParseIntError</code>. Then we try to parse the number, and add <code>?</code>. That means &quot;check if it is an error, and give what is inside the Result if it is okay&quot;. If it is not okay, it will return the error and end. But if it is okay, it will go to the next line. On the next line is the number inside of <code>Ok()</code>. We need to wrap it in <code>Ok</code> because the return is <code>Result&lt;i32, ParseIntError&gt;</code>, not <code>i32</code>.</p>
<p>Now, we can try out our function. Let's see what it does with a vec of <code>&amp;str</code>s.</p>
<pre><pre class="playground"><code class="language-rust">fn parse_str(input: &amp;str) -&gt; Result&lt;i32, std::num::ParseIntError&gt; {
let parsed_number = input.parse::&lt;i32&gt;()?;
Ok(parsed_number)
}
fn main() {
let str_vec = vec![&quot;Seven&quot;, &quot;8&quot;, &quot;9.0&quot;, &quot;nice&quot;, &quot;6060&quot;];
for item in str_vec {
let parsed = parse_str(item);
println!(&quot;{:?}&quot;, parsed);
}
}
</code></pre></pre>
<p>This prints:</p>
<pre><code class="language-text">Err(ParseIntError { kind: InvalidDigit })
Ok(8)
Err(ParseIntError { kind: InvalidDigit })
Err(ParseIntError { kind: InvalidDigit })
Ok(6060)
</code></pre>
<p>How did we find <code>std::num::ParseIntError</code>? One easy way is to &quot;ask&quot; the compiler again.</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
let failure = &quot;Not a number&quot;.parse::&lt;i32&gt;();
failure.rbrbrb(); // ⚠️ Compiler: &quot;What is rbrbrb()???&quot;
}
</code></pre></pre>
<p>The compiler doesn't understand, and says:</p>
<pre><code class="language-text">error[E0599]: no method named `rbrbrb` found for enum `std::result::Result&lt;i32, std::num::ParseIntError&gt;` in the current scope
--&gt; src\main.rs:3:13
|
3 | failure.rbrbrb();
| ^^^^^^ method not found in `std::result::Result&lt;i32, std::num::ParseIntError&gt;`
</code></pre>
<p>So <code>std::result::Result&lt;i32, std::num::ParseIntError&gt;</code> is the signature we need.</p>
<p>We don't need to write <code>std::result::Result</code> because <code>Result</code> is always &quot;in scope&quot; (in scope = ready to use). Rust does this for all the types we use a lot so we don't have to write <code>std::result::Result</code>, <code>std::collections::Vec</code>, etc.</p>
<p>We aren't working with things like files yet, so the ? operator doesn't look too useful yet. But here is a useless but quick example that shows how you can use it on a single line. Instead of making an <code>i32</code> with <code>.parse()</code>, we'll do a lot more. We'll make an <code>u16</code>, then turn it to a <code>String</code>, then a <code>u32</code>, then to a <code>String</code> again, and finally to a <code>i32</code>.</p>
<pre><pre class="playground"><code class="language-rust">use std::num::ParseIntError;
fn parse_str(input: &amp;str) -&gt; Result&lt;i32, ParseIntError&gt; {
let parsed_number = input.parse::&lt;u16&gt;()?.to_string().parse::&lt;u32&gt;()?.to_string().parse::&lt;i32&gt;()?; // Add a ? each time to check and pass it on
Ok(parsed_number)
}
fn main() {
let str_vec = vec![&quot;Seven&quot;, &quot;8&quot;, &quot;9.0&quot;, &quot;nice&quot;, &quot;6060&quot;];
for item in str_vec {
let parsed = parse_str(item);
println!(&quot;{:?}&quot;, parsed);
}
}
</code></pre></pre>
<p>This prints the same thing, but this time we handled three <code>Result</code>s in a single line. Later on we will do this with files, because they always return <code>Result</code>s because many things can go wrong.</p>
<p>Imagine the following: you want to open a file, write to it, and close it. First you need to successfully find the file (that's a <code>Result</code>). Then you need to successfully write to it (that's a <code>Result</code>). With <code>?</code> you can do that on one line.</p>
<h3 id="when-panic-and-unwrap-are-good"><a class="header" href="#when-panic-and-unwrap-are-good">When panic and unwrap are good</a></h3>
<p>Rust has a <code>panic!</code> macro that you can use to make it panic. It is easy to use:</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
panic!(&quot;Time to panic!&quot;);
}
</code></pre></pre>
<p>The message <code>&quot;Time to panic!&quot;</code> displays when you run the program: <code>thread 'main' panicked at 'Time to panic!', src\main.rs:2:3</code></p>
<p>You will remember that <code>src\main.rs</code> is the directory and file name, and <code>2:3</code> is the line and column name. With this information, you can find the code and fix it.</p>
<p><code>panic!</code> is a good macro to use to make sure that you know when something changes. For example, this function called <code>prints_three_things</code> always prints index [0], [1], and [2] from a vector. It is okay because we always give it a vector with three items:</p>
<pre><pre class="playground"><code class="language-rust">fn prints_three_things(vector: Vec&lt;i32&gt;) {
println!(&quot;{}, {}, {}&quot;, vector[0], vector[1], vector[2]);
}
fn main() {
let my_vec = vec![8, 9, 10];
prints_three_things(my_vec);
}
</code></pre></pre>
<p>It prints <code>8, 9, 10</code> and everything is fine.</p>
<p>But imagine that later on we write more and more code, and forget that <code>my_vec</code> can only be three things. Now <code>my_vec</code> in this part has six things:</p>
<pre><pre class="playground"><code class="language-rust">fn prints_three_things(vector: Vec&lt;i32&gt;) {
println!(&quot;{}, {}, {}&quot;, vector[0], vector[1], vector[2]);
}
fn main() {
let my_vec = vec![8, 9, 10, 10, 55, 99]; // Now my_vec has six things
prints_three_things(my_vec);
}
</code></pre></pre>
<p>No error happens, because [0] and [1] and [2] are all inside this longer <code>Vec</code>. But what if it was really important to only have three things? We wouldn't know that there was a problem because the program doesn't panic. We should have done this instead:</p>
<pre><pre class="playground"><code class="language-rust">fn prints_three_things(vector: Vec&lt;i32&gt;) {
if vector.len() != 3 {
panic!(&quot;my_vec must always have three items&quot;) // will panic if the length is not 3
}
println!(&quot;{}, {}, {}&quot;, vector[0], vector[1], vector[2]);
}
fn main() {
let my_vec = vec![8, 9, 10];
prints_three_things(my_vec);
}
</code></pre></pre>
<p>Now we will know if the vector has six items because it panics as it should:</p>
<pre><pre class="playground"><code class="language-rust"> // ⚠️
fn prints_three_things(vector: Vec&lt;i32&gt;) {
if vector.len() != 3 {
panic!(&quot;my_vec must always have three items&quot;)
}
println!(&quot;{}, {}, {}&quot;, vector[0], vector[1], vector[2]);
}
fn main() {
let my_vec = vec![8, 9, 10, 10, 55, 99];
prints_three_things(my_vec);
}
</code></pre></pre>
<p>This gives us <code>thread 'main' panicked at 'my_vec must always have three items', src\main.rs:8:9</code>. Thanks to <code>panic!</code>, we now remember that <code>my_vec</code> should only have three items. So <code>panic!</code> is a good macro to create reminders in your code.</p>
<p>There are three other macros that are similar to <code>panic!</code> that you use a lot in testing. They are: <code>assert!</code>, <code>assert_eq!</code>, and <code>assert_ne!</code>.</p>
<p>Here is what they mean:</p>
<ul>
<li><code>assert!()</code>: if the part inside <code>()</code> is not true, the program will panic.</li>
<li><code>assert_eq!()</code>: the two items inside <code>()</code> must be equal.</li>
<li><code>assert_ne!()</code>: the two items inside <code>()</code> must not be equal. (<em>ne</em> means not equal)</li>
</ul>
<p>Some examples:</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
let my_name = &quot;Loki Laufeyson&quot;;
assert!(my_name == &quot;Loki Laufeyson&quot;);
assert_eq!(my_name, &quot;Loki Laufeyson&quot;);
assert_ne!(my_name, &quot;Mithridates&quot;);
}
</code></pre></pre>
<p>This will do nothing, because all three assert macros are okay. (This is what we want)</p>
<p>You can also add a message if you want.</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
let my_name = &quot;Loki Laufeyson&quot;;
assert!(
my_name == &quot;Loki Laufeyson&quot;,
&quot;{} should be Loki Laufeyson&quot;,
my_name
);
assert_eq!(
my_name, &quot;Loki Laufeyson&quot;,
&quot;{} and Loki Laufeyson should be equal&quot;,
my_name
);
assert_ne!(
my_name, &quot;Mithridates&quot;,
&quot;You entered {}. Input must not equal Mithridates&quot;,
my_name
);
}
</code></pre></pre>
<p>These messages will only display if the program panics. So if you run this:</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
let my_name = &quot;Mithridates&quot;;
assert_ne!(
my_name, &quot;Mithridates&quot;,
&quot;You enter {}. Input must not equal Mithridates&quot;,
my_name
);
}
</code></pre></pre>
<p>It will display:</p>
<pre><code class="language-text">thread 'main' panicked at 'assertion failed: `(left != right)`
left: `&quot;Mithridates&quot;`,
right: `&quot;Mithridates&quot;`: You entered Mithridates. Input must not equal Mithridates', src\main.rs:4:5
</code></pre>
<p>So it is saying &quot;you said that left != right, but left == right&quot;. And it displays our message that says <code>You entered Mithridates. Input must not equal Mithridates</code>.</p>
<p><code>unwrap</code> is also good when you are writing your program and you want it to crash when there is a problem. Later, when your code is finished it is good to change <code>unwrap</code> to something else that won't crash.</p>
<p>You can also use <code>expect</code>, which is like <code>unwrap</code> but a bit better because you give it your own message. Textbooks usually give this advice: &quot;If you use <code>.unwrap()</code> a lot, at least use <code>.expect()</code> for better error messages.&quot;</p>
<p>This will crash:</p>
<pre><pre class="playground"><code class="language-rust"> // ⚠️
fn get_fourth(input: &amp;Vec&lt;i32&gt;) -&gt; i32 {
let fourth = input.get(3).unwrap();
*fourth
}
fn main() {
let my_vec = vec![9, 0, 10];
let fourth = get_fourth(&amp;my_vec);
}
</code></pre></pre>
<p>The error message is <code>thread 'main' panicked at 'called Option::unwrap() on a None value', src\main.rs:7:18</code>.</p>
<p>Now we write our own message with <code>expect</code>:</p>
<pre><pre class="playground"><code class="language-rust"> // ⚠️
fn get_fourth(input: &amp;Vec&lt;i32&gt;) -&gt; i32 {
let fourth = input.get(3).expect(&quot;Input vector needs at least 4 items&quot;);
*fourth
}
fn main() {
let my_vec = vec![9, 0, 10];
let fourth = get_fourth(&amp;my_vec);
}
</code></pre></pre>
<p>It crashes again, but the error is better: <code>thread 'main' panicked at 'Input vector needs at least 4 items', src\main.rs:7:18</code>. <code>.expect()</code> is a little better than <code>.unwrap()</code> because of this, but it will still panic on <code>None</code>. Now here is an example of a bad practice, a function that tries to unwrap two times. It takes a <code>Vec&lt;Option&lt;i32&gt;&gt;</code>, so maybe each part will have a <code>Some&lt;i32&gt;</code> or maybe a <code>None</code>.</p>
<pre><pre class="playground"><code class="language-rust">fn try_two_unwraps(input: Vec&lt;Option&lt;i32&gt;&gt;) {
println!(&quot;Index 0 is: {}&quot;, input[0].unwrap());
println!(&quot;Index 1 is: {}&quot;, input[1].unwrap());
}
fn main() {
let vector = vec![None, Some(1000)]; // This vector has a None, so it will panic
try_two_unwraps(vector);
}
</code></pre></pre>
<p>The message is: <code>thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src\main.rs:2:32</code>. We're not sure if it was the first <code>.unwrap()</code> or the second <code>.unwrap()</code> until we check the line. It would be better to check the length and also to not unwrap. But with <code>.expect()</code> at least it will be a <em>little</em> better. Here it is with <code>.expect()</code>:</p>
<pre><pre class="playground"><code class="language-rust">fn try_two_unwraps(input: Vec&lt;Option&lt;i32&gt;&gt;) {
println!(&quot;Index 0 is: {}&quot;, input[0].expect(&quot;The first unwrap had a None!&quot;));
println!(&quot;Index 1 is: {}&quot;, input[1].expect(&quot;The second unwrap had a None!&quot;));
}
fn main() {
let vector = vec![None, Some(1000)];
try_two_unwraps(vector);
}
</code></pre></pre>
<p>So that is a bit better: <code>thread 'main' panicked at 'The first unwrap had a None!', src\main.rs:2:32</code>. We have the line number as well so we can find it.</p>
<p>You can also use <code>unwrap_or</code> if you want to always have a value that you want to choose. If you do this it will never panic. That's:</p>
<ul>
<li>
<ol>
<li>good because your program won't panic, but</li>
</ol>
</li>
<li>
<ol start="2">
<li>maybe not good if you want the program to panic if there's a problem.</li>
</ol>
</li>
</ul>
<p>But usually we don't want our program to panic, so <code>unwrap_or</code> is a good method to use.</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
let my_vec = vec![8, 9, 10];
let fourth = my_vec.get(3).unwrap_or(&amp;0); // If .get doesn't work, we will make the value &amp;0.
// .get returns a reference, so we need &amp;0 and not 0
// You can write &quot;let *fourth&quot; with a * if you want fourth to be
// a 0 and not a &amp;0, but here we just print so it doesn't matter
println!(&quot;{}&quot;, fourth);
}
</code></pre></pre>
<p>This prints <code>0</code> because <code>.unwrap_or(&amp;0)</code> gives a 0 even if it is a <code>None</code>.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="Chapter_32.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_34.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_32.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_34.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>