easy_rust/Chapter_63.html
2020-12-25 14:16:02 +00:00

1217 lines
69 KiB
HTML

<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title> A tour of the standard library - 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"><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> RefCell</a></li><li class="chapter-item expanded "><a href="Chapter_43.html"><strong aria-hidden="true">44.</strong> Mutex</a></li><li class="chapter-item expanded "><a href="Chapter_44.html"><strong aria-hidden="true">45.</strong> RwLock</a></li><li class="chapter-item expanded "><a href="Chapter_45.html"><strong aria-hidden="true">46.</strong> Cow</a></li><li class="chapter-item expanded "><a href="Chapter_46.html"><strong aria-hidden="true">47.</strong> Type aliases</a></li><li class="chapter-item expanded "><a href="Chapter_47.html"><strong aria-hidden="true">48.</strong> The todo! macro</a></li><li class="chapter-item expanded "><a href="Chapter_48.html"><strong aria-hidden="true">49.</strong> Rc</a></li><li class="chapter-item expanded "><a href="Chapter_49.html"><strong aria-hidden="true">50.</strong> Multiple threads</a></li><li class="chapter-item expanded "><a href="Chapter_50.html"><strong aria-hidden="true">51.</strong> Closures in functions</a></li><li class="chapter-item expanded "><a href="Chapter_51.html"><strong aria-hidden="true">52.</strong> impl Trait</a></li><li class="chapter-item expanded "><a href="Chapter_52.html"><strong aria-hidden="true">53.</strong> Arc</a></li><li class="chapter-item expanded "><a href="Chapter_53.html"><strong aria-hidden="true">54.</strong> Channels</a></li><li class="chapter-item expanded "><a href="Chapter_54.html"><strong aria-hidden="true">55.</strong> Reading Rust documentation</a></li><li class="chapter-item expanded "><a href="Chapter_55.html"><strong aria-hidden="true">56.</strong> Attributes</a></li><li class="chapter-item expanded "><a href="Chapter_56.html"><strong aria-hidden="true">57.</strong> Box</a></li><li class="chapter-item expanded "><a href="Chapter_57.html"><strong aria-hidden="true">58.</strong> Box around traits</a></li><li class="chapter-item expanded "><a href="Chapter_58.html"><strong aria-hidden="true">59.</strong> Default and the builder pattern</a></li><li class="chapter-item expanded "><a href="Chapter_59.html"><strong aria-hidden="true">60.</strong> Deref and DerefMut</a></li><li class="chapter-item expanded "><a href="Chapter_60.html"><strong aria-hidden="true">61.</strong> Crates and modules</a></li><li class="chapter-item expanded "><a href="Chapter_61.html"><strong aria-hidden="true">62.</strong> Testing</a></li><li class="chapter-item expanded "><a href="Chapter_62.html"><strong aria-hidden="true">63.</strong> External crates</a></li><li class="chapter-item expanded "><a href="Chapter_63.html" class="active"><strong aria-hidden="true">64.</strong> A tour of the standard library</a></li><li class="chapter-item expanded "><a href="Chapter_64.html"><strong aria-hidden="true">65.</strong> Writing macros</a></li><li class="chapter-item expanded "><a href="Chapter_65.html"><strong aria-hidden="true">66.</strong> cargo</a></li><li class="chapter-item expanded "><a href="Chapter_66.html"><strong aria-hidden="true">67.</strong> Taking user input</a></li><li class="chapter-item expanded "><a href="Chapter_67.html"><strong aria-hidden="true">68.</strong> Using files</a></li><li class="chapter-item expanded "><a href="Chapter_68.html"><strong aria-hidden="true">69.</strong> cargo doc</a></li><li class="chapter-item expanded "><a href="Chapter_69.html"><strong aria-hidden="true">70.</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><a class="header" href="#a-tour-of-the-standard-library" id="a-tour-of-the-standard-library">A tour of the standard library</a></h2>
<p>Now that you know a lot of Rust, you will be able to understand most things inside the standard library. The code inside it isn't so scary anymore. Let's take a look at some of the parts in it that we haven't learned yet. This tour will go over most parts of the standard library that you don't need to install Rust for. We will revisit a lot of items we already know so we can learn them with greater understanding.</p>
<h3><a class="header" href="#arrays" id="arrays">Arrays</a></h3>
<p>One thing about arrays to note is that they don't implement <code>Iterator.</code>. That means that if you have an array, you can't use <code>for</code>. But you can use methods like <code>.iter()</code> on them. Or you can use <code>&amp;</code> to get a slice. Actually, the compiler will tell you exactly that if you try to use <code>for</code>:</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
// ⚠️
let my_cities = [&quot;Beirut&quot;, &quot;Tel Aviv&quot;, &quot;Nicosia&quot;];
for city in my_cities {
println!(&quot;{}&quot;, city);
}
}
</code></pre></pre>
<p>The message is:</p>
<pre><code class="language-text">error[E0277]: `[&amp;str; 3]` is not an iterator
--&gt; src\main.rs:5:17
|
| ^^^^^^^^^ borrow the array with `&amp;` or call `.iter()` on it to iterate over it
</code></pre>
<p>So let's try both. They give the same result.</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
let my_cities = [&quot;Beirut&quot;, &quot;Tel Aviv&quot;, &quot;Nicosia&quot;];
for city in &amp;my_cities {
println!(&quot;{}&quot;, city);
}
for city in my_cities.iter() {
println!(&quot;{}&quot;, city);
}
}
</code></pre></pre>
<p>This prints:</p>
<pre><code class="language-text">Beirut
Tel Aviv
Nicosia
Beirut
Tel Aviv
Nicosia
</code></pre>
<p>If you want to get variables from an array, you can put their names inside <code>[]</code> to destructure it. This is the same as using a tuple in <code>match</code> statements or to get variables from a struct.</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
let my_cities = [&quot;Beirut&quot;, &quot;Tel Aviv&quot;, &quot;Nicosia&quot;];
let [city1, city2, city3] = my_cities;
println!(&quot;{}&quot;, city1);
}
</code></pre></pre>
<p>This prints <code>Beirut</code>.</p>
<h3><a class="header" href="#char" id="char">char</a></h3>
<p>You can use the <code>.escape_unicode()</code> method to get the Unicode number for a <code>char</code>:</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
let korean_word = &quot;청춘예찬&quot;;
for character in korean_word.chars() {
print!(&quot;{} &quot;, character.escape_unicode());
}
}
</code></pre></pre>
<p>This prints <code>\u{ccad} \u{cd98} \u{c608} \u{cc2c}</code>.</p>
<p>You can get a char from <code>u8</code> using the <code>From</code> trait, but for a <code>u32</code> you use <code>TryFrom</code> because it might not work. There are many more numbers in <code>u32</code> than characters in Unicode. We can see this with a simple demonstration.</p>
<pre><pre class="playground"><code class="language-rust">use std::convert::TryFrom; // You need to brig TryFrom in to use it
use rand::prelude::*; // We will use random numbers too
fn main() {
let some_character = char::from(99); // This one is easy - no need for TryFrom
println!(&quot;{}&quot;, some_character);
let mut random_generator = rand::thread_rng();
// This will try 40,000 times to make a char from a u32.
// The range is 0 (std::u32::MIN) to u32's highest number (std::u32::MAX). If it doesn't work, we will give it '-'.
for _ in 0..40_000 {
let bigger_character = char::try_from(random_generator.gen_range(std::u32::MIN, std::u32::MAX)).unwrap_or('-');
print!(&quot;{}&quot;, bigger_character)
}
}
</code></pre></pre>
<p>Almost every time it will generate a <code>-</code>. This is part of the sort of output you will see:</p>
<pre><code class="language-text">------------------------------------------------------------------------𤒰---------------------
-----------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------
-------------------------------------------------------------춗--------------------------------
-----------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------
------------򇍜----------------------------------------------------
</code></pre>
<p>So it's a good thing you need to use <code>TryFrom</code>.</p>
<p>Also, as of late August 2020 you can now get a <code>String</code> from a <code>char</code>. (<code>String</code> implements <code>From&lt;char&gt;</code>) Just write <code>String::from()</code> and put a <code>char</code> inside.</p>
<h3><a class="header" href="#integers" id="integers">Integers</a></h3>
<p>There are a lot of math methods for these types, plus some others. Here are some of the most useful ones.</p>
<p><code>.checked_add()</code>, <code>.checked_sub()</code>, <code>.checked_mul()</code>, <code>.checked_div()</code>. These are good methods if you think you might get a number that won't fit into a type. They return an <code>Option</code> so you can safely check that your math works without making the program panic.</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
let some_number = 200_u8;
let other_number = 200_u8;
println!(&quot;{:?}&quot;, some_number.checked_add(other_number));
println!(&quot;{:?}&quot;, some_number.checked_add(1));
}
</code></pre></pre>
<p>This prints:</p>
<pre><code class="language-text">None
Some(201)
</code></pre>
<p>You'll notice that on the page for integers it says <code>rhs</code> a lot. This means &quot;right hand side&quot;, which is the right hand side when you do some math. For example, in <code>5 + 6</code>, <code>5</code> is on the left and <code>6</code> is on the right, so it's the <code>rhs</code>. This is not a keyword, but you will see it a lot so it's good to know.</p>
<p>While we are on the subject, let's learn how to implement <code>Add</code>. After you implement <code>Add</code>, you can use <code>+</code> on a type that you create. You need to implement <code>Add</code> yourself because add can mean a lot of things. Here's the example in the standard library page:</p>
<pre><pre class="playground"><code class="language-rust">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>use std::ops::Add; // first bring in Add
#[derive(Debug, Copy, Clone, PartialEq)] // PartialEq is probably the most important part here. You want to be able to compare numbers
struct Point {
x: i32,
y: i32,
}
impl Add for Point {
type Output = Self; // Remember, this is called an &quot;associated type&quot;: a &quot;type that goes together&quot;.
// In this case it's just another Point
fn add(self, other: Self) -&gt; Self {
Self {
x: self.x + other.x,
y: self.y + other.y,
}
}
}
<span class="boring">}
</span></code></pre></pre>
<p>Now let's implement <code>Add</code> for our own type. Let's imagine that we want to add two countries together so we can compare their economies. It looks like this:</p>
<pre><pre class="playground"><code class="language-rust">use std::fmt;
use std::ops::Add;
#[derive(Clone)]
struct Country {
name: String,
population: u32,
gdp: u32, // This is the size of the economy
}
impl Country {
fn new(name: &amp;str, population: u32, gdp: u32) -&gt; Self {
Self {
name: name.to_string(),
population,
gdp,
}
}
}
impl Add for Country {
type Output = Self;
fn add(self, other: Self) -&gt; Self {
Self {
name: format!(&quot;{} and {}&quot;, self.name, other.name), // We will add the names together,
population: self.population + other.population, // and the population,
gdp: self.gdp + other.gdp, // and the GDP
}
}
}
impl fmt::Display for Country {
fn fmt(&amp;self, f: &amp;mut fmt::Formatter&lt;'_&gt;) -&gt; fmt::Result {
write!(
f,
&quot;In {} are {} people and a GDP of ${}&quot;, // Then we can print them all with just {}
self.name, self.population, self.gdp
)
}
}
fn main() {
let nauru = Country::new(&quot;Nauru&quot;, 10_670, 160_000_000);
let vanuatu = Country::new(&quot;Vanuatu&quot;, 307_815, 820_000_000);
let micronesia = Country::new(&quot;Micronesia&quot;, 104_468, 367_000_000);
// We could have given Country a &amp;str instead of a String for the name. But we would have to write lifetimes everywhere
// and that would be too much for a small example. Better to just clone them when we call println!.
println!(&quot;{}&quot;, nauru.clone());
println!(&quot;{}&quot;, nauru.clone() + vanuatu.clone());
println!(&quot;{}&quot;, nauru + vanuatu + micronesia);
}
</code></pre></pre>
<p>This prints:</p>
<pre><code class="language-text">In Nauru are 10670 people and a GDP of $160000000
In Nauru and Vanuatu are 318485 people and a GDP of $980000000
In Nauru and Vanuatu and Micronesia are 422953 people and a GDP of $1347000000
</code></pre>
<p>Later on in this code we could change <code>.fmt()</code> to display a number that is easier to read.</p>
<p>The three others are called <code>Sub</code>, <code>Mul</code>, and <code>Div</code>, and they are basically the same to implement. For <code>+=</code>, <code>-=</code>, <code>*=</code> and <code>/=</code>, just add <code>Assign</code>: <code>AddAssign</code>, <code>SubAssign</code>, <code>MulAssign</code>, and <code>DivAssign</code>. You can see the full list <a href="https://doc.rust-lang.org/std/ops/index.html#structs">here</a>, because there are many more. <code>%</code> for example is called <code>Rem</code>, <code>-</code> is called <code>Neg</code>, and so on.</p>
<h3><a class="header" href="#floats" id="floats">Floats</a></h3>
<p><code>f32</code> and <code>f64</code> have a very large number of methods that you use when doing math. We won't look at those, but here are some methods that you might use. They are: <code>.floor()</code>, <code>.ceil()</code>, <code>.round()</code>, and <code>.trunc()</code>. All of these return an <code>f32</code> or <code>f64</code> that is like an integer, with only <code>0</code> after the period. They do this:</p>
<ul>
<li><code>.floor()</code>: gives you the next lowest integer.</li>
<li><code>.ceil()</code>: gives you the next highest integer.</li>
<li><code>.round()</code>: gives you a higher number if 0.5 or more, or the same number if less than 0.5. This is called rounding because it gives you a &quot;round&quot; number (a number that has a short, simple form).</li>
<li><code>.trunc()</code>: just cuts off the part after the period. Truncate means &quot;to cut off&quot;.</li>
</ul>
<p>Here is a simple function to print them.</p>
<pre><pre class="playground"><code class="language-rust">fn four_operations(input: f64) {
println!(
&quot;For the number {}:
floor: {}
ceiling: {}
rounded: {}
truncated: {}\n&quot;,
input,
input.floor(),
input.ceil(),
input.round(),
input.trunc()
);
}
fn main() {
four_operations(9.1);
four_operations(100.7);
four_operations(-1.1);
four_operations(-19.9);
}
</code></pre></pre>
<p>This prints:</p>
<pre><code class="language-text">For the number 9.1:
floor: 9
ceiling: 10
rounded: 9 // because less than 9.5
truncated: 9
For the number 100.7:
floor: 100
ceiling: 101
rounded: 101 // because more than 100.5
truncated: 100
For the number -1.1:
floor: -2
ceiling: -1
rounded: -1
truncated: -1
For the number -19.9:
floor: -20
ceiling: -19
rounded: -20
truncated: -19
</code></pre>
<p><code>f32</code> and <code>f64</code> have a method called <code>.max()</code> and <code>.min()</code> that gives you the higher or the lower of two numbers. (For other types you can just use <code>std::cmp::max</code> and <code>std::cmp::min</code>.) Here is a way to use this with <code>.fold()</code> to get the highest or lowest number. You can see again that <code>.fold()</code> isn't just for adding numbers.</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
let my_vec = vec![8.0_f64, 7.6, 9.4, 10.0, 22.0, 77.345, 10.22, 3.2, -7.77, -10.0];
let maximum = my_vec.iter().fold(f64::MIN, |current_number, next_number| current_number.max(*next_number)); // Note: start with the lowest possible number for an f64.
let minimum = my_vec.iter().fold(f64::MAX, |current_number, next_number| current_number.min(*next_number)); // And here start with the highest possible number
println!(&quot;{}, {}&quot;, maximum, minimum);
}
</code></pre></pre>
<h3><a class="header" href="#bool" id="bool">bool</a></h3>
<p>In Rust you can turn a <code>bool</code> into an integer if you want, because it's safe to do that. But you can't do it the other way around. As you can see, <code>true</code> turns to 1 and <code>false</code> turns to 0.</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
let true_false = (true, false);
println!(&quot;{} {}&quot;, true_false.0 as u8, true_false.1 as i32);
}
</code></pre></pre>
<p>This prints <code>1 0</code>. Or you can use <code>.into()</code> if you tell the compiler the type:</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
let true_false: (i128, u16) = (true.into(), false.into());
println!(&quot;{} {}&quot;, true_false.0, true_false.1);
}
</code></pre></pre>
<p>This prints the same thing.</p>
<h3><a class="header" href="#vec" id="vec">Vec</a></h3>
<p>Vec has a lot of methods that we haven't looked at yet. Let's start with <code>.sort()</code>. <code>.sort()</code> is not surprising at all. It uses a <code>&amp;mut self</code> to sort a vector.</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
let mut my_vec = vec![100, 90, 80, 0, 0, 0, 0, 0];
my_vec.sort();
println!(&quot;{:?}&quot;, my_vec);
}
</code></pre></pre>
<p>This prints <code>[0, 0, 0, 0, 0, 80, 90, 100]</code>. But there is one more interesting way to sort called <code>.sort_unstable()</code>, and it is usually faster. It can be faster because it doesn't care about the order of numbers if they are the same number. In regular <code>.sort()</code>, you know that the last <code>0, 0, 0, 0, 0</code> will be in the same order after <code>.sort()</code>. But <code>.sort_unstable()</code> might move the last zero to index 0, then the third last zero to index 2, etc.</p>
<p><code>.dedup()</code> means &quot;de-duplicate&quot;. It will remove items that are the same in a vector, but only if they are next to each other. This next code will not just print <code>&quot;sun&quot;, &quot;moon&quot;</code>:</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
let mut my_vec = vec![&quot;sun&quot;, &quot;sun&quot;, &quot;moon&quot;, &quot;moon&quot;, &quot;sun&quot;, &quot;moon&quot;, &quot;moon&quot;];
my_vec.dedup();
println!(&quot;{:?}&quot;, my_vec);
}
</code></pre></pre>
<p>It only gets rid of &quot;sun&quot; next to the other &quot;sun&quot;, then &quot;moon&quot; next to one &quot;moon&quot;, and again with &quot;moon&quot; next to another &quot;moon&quot;. The result is: <code>[&quot;sun&quot;, &quot;moon&quot;, &quot;sun&quot;, &quot;moon&quot;]</code>.</p>
<p>If you want to remove every duplicate, just <code>.sort()</code> first:</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
let mut my_vec = vec![&quot;sun&quot;, &quot;sun&quot;, &quot;moon&quot;, &quot;moon&quot;, &quot;sun&quot;, &quot;moon&quot;, &quot;moon&quot;];
my_vec.sort();
my_vec.dedup();
println!(&quot;{:?}&quot;, my_vec);
}
</code></pre></pre>
<p>Result: <code>[&quot;moon&quot;, &quot;sun&quot;]</code>.</p>
<h3><a class="header" href="#string" id="string">String</a></h3>
<p>You will remember that a <code>String</code> is kind of like a <code>Vec</code>. It is so like a <code>Vec</code> that you can do a lot of the same methods. For example, you can start one with <code>String::with_capacity()</code>. You want that if you are always going to be pushing a <code>char</code> with <code>.push()</code> or pushing a <code>&amp;str</code> with <code>.push_str()</code>. Here's an example of a <code>String</code> that has too many allocations.</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
let mut push_string = String::new();
let mut capacity_counter = 0; // capacity starts at 0
for _ in 0..100_000 { // Do this 100,000 times
if push_string.capacity() != capacity_counter { // First check if capacity is different now
println!(&quot;{}&quot;, push_string.capacity()); // If it is, print it
capacity_counter = push_string.capacity(); // then update the counter
}
push_string.push_str(&quot;I'm getting pushed into the string!&quot;); // and push this in every time
}
}
</code></pre></pre>
<p>This prints:</p>
<pre><code class="language-text">35
70
140
280
560
1120
2240
4480
8960
17920
35840
71680
143360
286720
573440
1146880
2293760
4587520
</code></pre>
<p>We had to reallocate (copy everything over) 18 times. But now we know the final capacity. So we'll give it the capacity right away, and we don't need to reallocate: just one <code>String</code> capacity is enough.</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
let mut push_string = String::with_capacity(4587520); // We know the exact number. Some different big number could work too
let mut capacity_counter = 0;
for _ in 0..100_000 {
if push_string.capacity() != capacity_counter {
println!(&quot;{}&quot;, push_string.capacity());
capacity_counter = push_string.capacity();
}
push_string.push_str(&quot;I'm getting pushed into the string!&quot;);
}
}
</code></pre></pre>
<p>And this prints <code>4587520</code>. Perfect! We never had to allocate again.</p>
<p>Of course, the actual length is certainly smaller than this. If you try 100,001 times, 101,000 times, etc., it'll still say <code>4587520</code>. That's because each time the capacity is two times what it was before. We can shrink it though with <code>.shrink_to_fit()</code> (same as for a <code>Vec</code>). Our <code>String</code> is very large and we don't want to add anything more to it, so we can make it a bit smaller. But only do this if you are sure. Here is why:</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
let mut push_string = String::with_capacity(4587520);
let mut capacity_counter = 0;
for _ in 0..100_000 {
if push_string.capacity() != capacity_counter {
println!(&quot;{}&quot;, push_string.capacity());
capacity_counter = push_string.capacity();
}
push_string.push_str(&quot;I'm getting pushed into the string!&quot;);
}
push_string.shrink_to_fit();
println!(&quot;{}&quot;, push_string.capacity());
push_string.push('a');
println!(&quot;{}&quot;, push_string.capacity());
push_string.shrink_to_fit();
println!(&quot;{}&quot;, push_string.capacity());
}
</code></pre></pre>
<p>This prints:</p>
<pre><code class="language-text">4587520
3500000
7000000
3500001
</code></pre>
<p>So first we had a size of <code>4587520</code>, but we weren't using it all. We used <code>.shrink_to_fit()</code> and got the size down to <code>3500000</code>. But then we forget that we needed to push an <code>a</code> on. When we did that, Rust saw that we needed more space and gave us double: now it's <code>7000000</code>. Whoops! So we did <code>.shrink_to_fit()</code> again and now it's back down to <code>3500001</code>.</p>
<p><code>.pop()</code> works for a <code>String</code>, just like for a <code>Vec</code>.</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
let mut my_string = String::from(&quot;.daer ot drah tib elttil a si gnirts sihT&quot;);
loop {
let pop_result = my_string.pop();
match pop_result {
Some(character) =&gt; print!(&quot;{}&quot;, character),
None =&gt; break,
}
}
}
</code></pre></pre>
<p>This prints <code>This string is a little bit hard to read.</code> because it starts from the last character.</p>
<p><code>.retain()</code> is a method that uses a closure, which is rare for <code>String</code>. It's just like <code>.filter()</code> for an iterator.</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
let mut my_string = String::from(&quot;Age: 20 Height: 194 Weight: 80&quot;);
my_string.retain(|character| character.is_alphabetic() || character == ' '); // Keep if a letter or a space
dbg!(my_string); // Let's use dbg!() for fun this time instead of println!
}
</code></pre></pre>
<p>This prints:</p>
<pre><code class="language-text">[src\main.rs:4] my_string = &quot;Age Height Weight &quot;
</code></pre>
<h3><a class="header" href="#osstring-and-cstring" id="osstring-and-cstring">OsString and CString</a></h3>
<p><code>std::ffi</code> is the part of <code>std</code> that helps you use Rust with other languages or operating systems. It has types like <code>OsString</code> and <code>CString</code>, which are like <code>String</code> for the operating system or <code>String</code> for the language C. They each have their own <code>&amp;str</code> type too: <code>OsStr</code> and <code>CStr</code>. <code>ffi</code> means &quot;foreign function interface&quot;.</p>
<p>You can use <code>OsString</code> when you have to work with an operating system that doesn't have Unicode. All Rust strings are unicode, but not every operating system has it. Here is the simple English explanation from the standard library on why we have <code>OsString</code>:</p>
<ul>
<li>A string on Unix (Linux, etc.) might be lots of bytes together that don't have zeros. And sometimes you read them as Unicode UTF-8.</li>
<li>A string on Windows might be made of random 16-bit values that don't have zeros. And sometimes you read them as Unicode UTF-16.</li>
<li>In Rust, strings are always valid UTF-8, which may contain zeros.</li>
</ul>
<p>So an <code>OsString</code> is made to be read by all of them.</p>
<p>You can do all the regular things with an <code>OsString</code> like <code>OsString::from(&quot;Write something here&quot;)</code>. It also has an interesting method called <code>.into_string()</code> that tries to make it into a regular <code>String</code>. It returns a <code>Result</code>, but the <code>Err</code> part is just the original <code>OsString</code>:</p>
<pre><pre class="playground"><code class="language-rust">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>// 🚧
pub fn into_string(self) -&gt; Result&lt;String, OsString&gt;
<span class="boring">}
</span></code></pre></pre>
<p>So if it doesn't work then you just get it back. You can't call <code>.unwrap()</code> because it will panic, but you can use <code>match</code> to get the <code>OsString</code> back. Let's test it out by calling methods that don't exist.</p>
<pre><pre class="playground"><code class="language-rust">use std::ffi::OsString;
fn main() {
// ⚠️
let os_string = OsString::from(&quot;This string works for your OS too.&quot;);
match os_string.into_string() {
Ok(valid) =&gt; valid.thth(), // Compiler: &quot;What's .thth()??&quot;
Err(not_valid) =&gt; not_valid.occg(), // Compiler: &quot;What's .occg()??&quot;
}
}
</code></pre></pre>
<p>Then the compiler tells us exactly what we want to know:</p>
<pre><code class="language-text">error[E0599]: no method named `thth` found for struct `std::string::String` in the current scope
--&gt; src/main.rs:6:28
|
6 | Ok(valid) =&gt; valid.thth(),
| ^^^^ method not found in `std::string::String`
error[E0599]: no method named `occg` found for struct `std::ffi::OsString` in the current scope
--&gt; src/main.rs:7:37
|
7 | Err(not_valid) =&gt; not_valid.occg(),
| ^^^^ method not found in `std::ffi::OsString`
</code></pre>
<p>We can see that the type of <code>valid</code> is <code>String</code> and the type of <code>not_valid</code> is <code>OsString</code>.</p>
<h3><a class="header" href="#mem" id="mem">mem</a></h3>
<p><code>std::mem</code> has some pretty interesting methods. We saw some of them already, such as <code>.size_of()</code>, <code>.size_of_val()</code> and <code>.drop()</code>:</p>
<pre><pre class="playground"><code class="language-rust">use std::mem;
fn main() {
println!(&quot;{}&quot;, mem::size_of::&lt;i32&gt;());
let my_array = [8; 50];
println!(&quot;{}&quot;, mem::size_of_val(&amp;my_array));
let mut some_string = String::from(&quot;You can drop a String because it's on the heap&quot;);
mem::drop(some_string);
// some_string.clear(); If we did this it would panic
}
</code></pre></pre>
<p>This prints:</p>
<pre><code class="language-text">4
200
</code></pre>
<p>Here are some other methods in <code>mem</code>:</p>
<p><code>swap()</code>: with this you can change the values between two variables. You use a mutable reference for each to do it. This is helpful when you have two things you want to switch and Rust doesn't let you because of borrowing rules. Or just when you want to quickly switch two things.</p>
<p>Here's one example:</p>
<pre><pre class="playground"><code class="language-rust">use std::{mem, fmt};
struct Ring { // Create a ring from Lord of the Rings
owner: String,
former_owner: String,
seeker: String, // seeker means &quot;person looking for it&quot;
}
impl Ring {
fn new(owner: &amp;str, former_owner: &amp;str, seeker: &amp;str) -&gt; Self {
Self {
owner: owner.to_string(),
former_owner: former_owner.to_string(),
seeker: seeker.to_string(),
}
}
}
impl fmt::Display for Ring { // Display to show who has it and who wants it
fn fmt(&amp;self, f: &amp;mut fmt::Formatter&lt;'_&gt;) -&gt; fmt::Result {
write!(f, &quot;{} has the ring, {} used to have it, and {} wants it&quot;, self.owner, self.former_owner, self.seeker)
}
}
fn main() {
let mut one_ring = Ring::new(&quot;Frodo&quot;, &quot;Gollum&quot;, &quot;Sauron&quot;);
println!(&quot;{}&quot;, one_ring);
mem::swap(&amp;mut one_ring.owner, &amp;mut one_ring.former_owner); // Gollum got the ring back for a second
println!(&quot;{}&quot;, one_ring);
}
</code></pre></pre>
<p>This will print:</p>
<pre><code class="language-text">Frodo has the ring, Gollum used to have it, and Sauron wants it
Gollum has the ring, Frodo used to have it, and Sauron wants it
</code></pre>
<p><code>replace()</code>: this is like swap, and actually uses swap inside it, as you can see:</p>
<pre><pre class="playground"><code class="language-rust">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>pub fn replace&lt;T&gt;(dest: &amp;mut T, mut src: T) -&gt; T {
swap(dest, &amp;mut src);
src
}
<span class="boring">}
</span></code></pre></pre>
<p>So it just does a swap and then returns the other item. With this you replace the value with something else you put in. And since it returns the old value, so you should use it with <code>let</code>. Here's a quick example.</p>
<pre><pre class="playground"><code class="language-rust">use std::mem;
struct City {
name: String,
}
impl City {
fn change_name(&amp;mut self, name: &amp;str) {
let old_name = mem::replace(&amp;mut self.name, name.to_string());
println!(
&quot;The city once called {} is now called {}.&quot;,
old_name, self.name
);
}
}
fn main() {
let mut capital_city = City {
name: &quot;Constantinople&quot;.to_string(),
};
capital_city.change_name(&quot;Istanbul&quot;);
}
</code></pre></pre>
<p>This prints <code>The city once called Constantinople is now called Istanbul.</code>.</p>
<p>One function called <code>.take()</code> is like <code>.replace()</code> but it leaves the default value in the item. You will remember that default values are usually things like 0, &quot;&quot;, and so on. Here is the signature:</p>
<pre><pre class="playground"><code class="language-rust">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>// 🚧
pub fn take&lt;T&gt;(dest: &amp;mut T) -&gt; T
where
T: Default,
<span class="boring">}
</span></code></pre></pre>
<p>So you can do something like this:</p>
<pre><pre class="playground"><code class="language-rust">use std::mem;
fn main() {
let mut number_vec = vec![8, 7, 0, 2, 49, 9999];
let mut new_vec = vec![];
number_vec.iter_mut().for_each(|number| {
let taker = mem::take(number);
new_vec.push(taker);
});
println!(&quot;{:?}\n{:?}&quot;, number_vec, new_vec);
}
</code></pre></pre>
<p>And as you can see, it replaced all the numbers with 0: no index was deleted.</p>
<pre><code class="language-text">[0, 0, 0, 0, 0, 0]
[8, 7, 0, 2, 49, 9999]
</code></pre>
<p>Of course, for your own type you can implement <code>Default</code> to whatever you want. Let's look at an example where we have a <code>Bank</code> and a <code>Robber</code>. Every time he robs the <code>Bank</code>, he gets the money at the desk. But the desk can take money from the back any time, so it always has 50. We will make our own type for this so it will always have 50. Here is how it works:</p>
<pre><pre class="playground"><code class="language-rust">use std::mem;
use std::ops::{Deref, DerefMut}; // We will use this to get the power of u32
struct Bank {
money_inside: u32,
money_at_desk: DeskMoney, // This is our &quot;smart pointer&quot; type. It has its own default, but it will use u32
}
struct DeskMoney(u32);
impl Default for DeskMoney {
fn default() -&gt; Self {
Self(50) // default is always 50, not 0
}
}
impl Deref for DeskMoney { // With this we can access the u32 using *
type Target = u32;
fn deref(&amp;self) -&gt; &amp;Self::Target {
&amp;self.0
}
}
impl DerefMut for DeskMoney { // And with this we can add, subtract, etc.
fn deref_mut(&amp;mut self) -&gt; &amp;mut Self::Target {
&amp;mut self.0
}
}
impl Bank {
fn check_money(&amp;self) {
println!(
&quot;There is ${} in the back and ${} at the desk.\n&quot;,
self.money_inside, *self.money_at_desk // Use * so we can just print the u32
);
}
}
struct Robber {
money_in_pocket: u32,
}
impl Robber {
fn check_money(&amp;self) {
println!(&quot;The robber has ${} right now.\n&quot;, self.money_in_pocket);
}
fn rob_bank(&amp;mut self, bank: &amp;mut Bank) {
let new_money = mem::take(&amp;mut bank.money_at_desk); // Here it takes the money, and leaves 50 because that is the default
self.money_in_pocket += *new_money; // Use * because we can only add u32. DeskMoney can't add
bank.money_inside -= *new_money; // Same here
println!(&quot;She robbed the bank. She now has ${}!\n&quot;, self.money_in_pocket);
}
}
fn main() {
let mut bank_of_klezkavania = Bank { // Set up our bank
money_inside: 5000,
money_at_desk: DeskMoney(50),
};
bank_of_klezkavania.check_money();
let mut robber = Robber { // Set up our robber
money_in_pocket: 50,
};
robber.check_money();
robber.rob_bank(&amp;mut bank_of_klezkavania); // Rob, then check money
robber.check_money();
bank_of_klezkavania.check_money();
robber.rob_bank(&amp;mut bank_of_klezkavania); // Do it again
robber.check_money();
bank_of_klezkavania.check_money();
}
</code></pre></pre>
<p>This will print:</p>
<pre><code class="language-text">There is $5000 in the back and $50 at the desk.
The robber has $50 right now.
She robbed the bank. She now has $100!
The robber has $100 right now.
There is $4950 in the back and $50 at the desk.
She robbed the bank. She now has $150!
The robber has $150 right now.
There is $4900 in the back and $50 at the desk.
</code></pre>
<p>You can see that there is always $50 at the desk.</p>
<h3><a class="header" href="#prelude" id="prelude">prelude</a></h3>
<p>The standard library has a prelude too, which is why you don't have to write things like <code>use std::vec::Vec</code> to create a <code>Vec</code>. You can see all the items <a href="https://doc.rust-lang.org/std/prelude/index.html#prelude-contents">here</a>, and will already know almost all of them:</p>
<ul>
<li><code>std::marker::{Copy, Send, Sized, Sync, Unpin}</code>. You haven't seen <code>Unpin</code> before, because it is used for almost every type (like <code>Sized</code>, which is also very common). To &quot;pin&quot; means to not let something move. In this case a <code>Pin</code> means that it can't move in memory, but most items have <code>Unpin</code> so you can. That's why functions like <code>std::mem::replace</code> work, because they aren't pinned.</li>
<li><code>std::ops::{Drop, Fn, FnMut, FnOnce}</code>.</li>
<li><code>std::mem::drop</code></li>
<li><code>std::boxed::Box</code>.</li>
<li><code>std::borrow::ToOwned</code>. You saw this before a bit with <code>Cow</code>, which can take borrowed content and make it owned. It uses <code>.to_owned()</code> to do this. You can also use <code>.to_owned()</code> on a <code>&amp;str</code> to get a <code>String</code>, and the same for other borrowed values.</li>
<li><code>std::clone::Clone</code></li>
<li><code>std::cmp::{PartialEq, PartialOrd, Eq, Ord}</code>.</li>
<li><code>std::convert::{AsRef, AsMut, Into, From}</code>.</li>
<li><code>std::default::Default</code>.</li>
<li><code>std::iter::{Iterator, Extend, IntoIterator, DoubleEndedIterator, ExactSizeIterator}</code>. We used <code>.rev()</code> for an iterator before: this actually makes a <code>DoubleEndedIterator</code>. An <code>ExactSizeIterator</code> is just something like <code>0..10</code>: it already knows that it has a <code>.len()</code> of 10. Other iterators don't know their length for sure.</li>
<li><code>std::option::Option::{self, Some, None}</code>.</li>
<li><code>std::result::Result::{self, Ok, Err}</code>.</li>
<li><code>std::string::{String, ToString}</code>.</li>
<li><code>std::vec::Vec</code>.</li>
</ul>
<p>What if you don't want the prelude for some reason? Just add the attribute <code>#![no_implicit_prelude]</code>. Let's give it a try and watch the compiler complain:</p>
<pre><pre class="playground"><code class="language-rust">// ⚠️
#![no_implicit_prelude]
fn main() {
let my_vec = vec![8, 9, 10];
let my_string = String::from(&quot;This won't work&quot;);
println!(&quot;{:?}, {}&quot;, my_vec, my_string);
}
</code></pre></pre>
<p>Now Rust has no idea what you are trying to do:</p>
<pre><code class="language-text">error: cannot find macro `println` in this scope
--&gt; src/main.rs:5:5
|
5 | println!(&quot;{:?}, {}&quot;, my_vec, my_string);
| ^^^^^^^
error: cannot find macro `vec` in this scope
--&gt; src/main.rs:3:18
|
3 | let my_vec = vec![8, 9, 10];
| ^^^
error[E0433]: failed to resolve: use of undeclared type or module `String`
--&gt; src/main.rs:4:21
|
4 | let my_string = String::from(&quot;This won't work&quot;);
| ^^^^^^ use of undeclared type or module `String`
error: aborting due to 3 previous errors
</code></pre>
<p>So for this simple code you need to tell Rust to use the <code>extern</code> (external) crate called <code>std</code>, and then the items you want. Here is everything we have to do just to create a Vec and a String and print it:</p>
<pre><pre class="playground"><code class="language-rust">#![no_implicit_prelude]
extern crate std; // Now you have to tell Rust that you want to use a crate called std
use std::vec; // We need the vec macro
use std::string::String; // and string
use std::convert::From; // and this to convert from a &amp;str to the String
use std::println; // and this to print
fn main() {
let my_vec = vec![8, 9, 10];
let my_string = String::from(&quot;This won't work&quot;);
println!(&quot;{:?}, {}&quot;, my_vec, my_string);
}
</code></pre></pre>
<p>And now it finally works, printing <code>[8, 9, 10], This won't work</code>. So you can see why Rust uses the prelude. But if you want, you don't need to use it. And you can even use <code>#![no_std]</code> (we saw this once) for when you can't even use something like stack memory. But most of the time you don't have to think about not using the prelude or <code>std</code> at all.</p>
<p>So why didn't we see the <code>extern</code> keyword before? It's because you don't need it that much anymore. Before, when bringing in an external crate you had to use it. So to use <code>rand</code> in the past, you had to write:</p>
<pre><pre class="playground"><code class="language-rust">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>extern crate rand;
<span class="boring">}
</span></code></pre></pre>
<p>and then <code>use</code> statements for the mods, traits, etc. that you wanted to use. But the Rust compiler now doesn't need this help anymore - you can just use <code>use</code> and it knows where to find it. So you almost never need <code>extern crate</code> anymore, but in other people's Rust code you might still see it on the top.</p>
<h3><a class="header" href="#time" id="time">time</a></h3>
<p><code>std::time</code> is where you can get functions for time. (If you want even more functions, a crate like <code>chrono</code> can work.) The simplest function is just getting the system time with <code>Instant::now()</code>.</p>
<pre><pre class="playground"><code class="language-rust">use std::time::Instant;
fn main() {
let time = Instant::now();
println!(&quot;{:?}&quot;, time);
}
</code></pre></pre>
<p>If you print it, you'll get something like this: <code>Instant { tv_sec: 2738771, tv_nsec: 685628140 }</code>. That's talking about seconds and nanoseconds, but it's not very useful. If you look at 2738771 seconds for example (written in August), it is 31.70 days. That doesn't have anything to do with the month or the day of the year. But the page on <code>Instant</code> tells us that it isn't supposed to be useful on its own. It says that it is &quot;opaque and useful only with Duration.&quot; Opaque means &quot;you can't figure it out&quot;, and duration means &quot;how much time passed&quot;. So it's only useful when doing things like comparing times.</p>
<p>If you look at the traits on the left, one of them is <code>Sub&lt;Instant&gt;</code>. That means we can use <code>-</code> to subtract one from another. And when we click on [src] to see what it does, it says:</p>
<pre><pre class="playground"><code class="language-rust">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>impl Sub&lt;Instant&gt; for Instant {
type Output = Duration;
fn sub(self, other: Instant) -&gt; Duration {
self.duration_since(other)
}
}
<span class="boring">}
</span></code></pre></pre>
<p>So it takes an <code>Instant</code> and uses <code>.duration_since()</code> to give a <code>Duration</code>. Let's try printing that. We'll make two <code>Instant::now()</code>s right next to each other, then we'll make the program busy for a while. Then we'll make one more <code>Instant::now()</code>. Finally, we'll see how long it took.</p>
<pre><pre class="playground"><code class="language-rust">use std::time::Instant;
fn main() {
let time1 = Instant::now();
let time2 = Instant::now(); // These two are right next to each other
let mut new_string = String::new();
loop {
new_string.push('წ'); // Make Rust push this Georgian letter onto the String
if new_string.len() &gt; 100_000 { // until it is 100,000 bytes long
break;
}
}
let time3 = Instant::now();
println!(&quot;{:?}&quot;, time2 - time1);
println!(&quot;{:?}&quot;, time3 - time1);
}
</code></pre></pre>
<p>This will print something like this:</p>
<pre><code class="language-text">1.025µs
683.378µs
</code></pre>
<p>So that's just over 1 microsecond vs. 683 microseconds. We can see that Rust did take some time to do it.</p>
<p>There is one fun thing we can do with just a single <code>Instant</code> though. We can turn it into a <code>String</code> with <code>format!(&quot;{:?}&quot;, Instant::now());</code>. It looks like this:</p>
<pre><pre class="playground"><code class="language-rust">use std::time::Instant;
fn main() {
let time1 = format!(&quot;{:?}&quot;, Instant::now());
println!(&quot;{}&quot;, time1);
}
</code></pre></pre>
<p>That prints something like <code>Instant { tv_sec: 2740773, tv_nsec: 632821036 }</code>. That's not useful, but if we use <code>.iter()</code> and <code>.rev()</code> and <code>.skip(2)</code>, we can skip the <code>}</code> and <code> </code> at the end. We can use it to make a random number generator.</p>
<pre><pre class="playground"><code class="language-rust">use std::time::Instant;
fn bad_random_number(digits: usize) {
if digits &gt; 9 {
panic!(&quot;Random number can only be up to 9 digits&quot;);
}
let now = Instant::now();
let output = format!(&quot;{:?}&quot;, now);
output
.chars()
.rev()
.skip(2)
.take(digits)
.for_each(|character| print!(&quot;{}&quot;, character));
println!();
}
fn main() {
bad_random_number(1);
bad_random_number(1);
bad_random_number(3);
bad_random_number(3);
}
</code></pre></pre>
<p>This will print something like:</p>
<pre><code class="language-text">6
4
967
180
</code></pre>
<p>The function is called <code>bad_random_number</code> because it's not a very good random number generator. Rust has better crates that make random numbers with less code than <code>rand</code> like <code>fastrand</code>. But it's a good example of how you can use your imagination to do something with <code>Instant</code>.</p>
<p>When you have a thread, you can use <code>std::thread::sleep</code> to make it stop for a while. When you do this, you have to give it a duration. You don't have to make more than one thread to do this because every program is on at least one thread. <code>sleep</code> needs a <code>Duration</code> though, so it can know how long to sleep. You can pick the unit like this: <code>Duration::from_millis()</code>, <code>Duration::from_secs</code>, etc. Here's one example:</p>
<pre><pre class="playground"><code class="language-rust">use std::time::Duration;
use std::thread::sleep;
fn main() {
let three_seconds = Duration::from_secs(3);
println!(&quot;I must sleep now.&quot;);
sleep(three_seconds);
println!(&quot;Did I miss anything?&quot;);
}
</code></pre></pre>
<p>This will just print</p>
<pre><code class="language-text">I must sleep now.
Did I miss anything?
</code></pre>
<p>but the thread will do nothing for three seconds. You usually use <code>.sleep()</code> when you have many threads that need to try something a lot, like connecting. You don't want the thread to use your processor to try 100,000 times in a second when you just want it to check sometimes. So then you can set a <code>Duration</code>, and it will try to do its task every time it wakes up.</p>
<h3><a class="header" href="#other-macros" id="other-macros">Other macros</a></h3>
<p>Let's take a look at some other macros.</p>
<p><code>unreachable!()</code></p>
<p>This macro is kind of like <code>todo!()</code> except it's for code that you will never do. Maybe you have a <code>match</code> in an enum that you know will never choose one of the arms, so the code can never be reached. If that's so, you can write <code>unreachable!()</code> so the compiler knows that it can ignore that part.</p>
<p>For example, let's say you have a program that writes something when you choose a place to live in. They are in Ukraine, and all of them are nice except Chernobyl. Your program doesn't let anyone choose Chernobyl, because it's not a good place to live right now. But the enum was made a long time ago in someone else's code, and you can't change it. So in the <code>match</code> arm you can use the macro here. It looks like this:</p>
<pre><pre class="playground"><code class="language-rust">enum UkrainePlaces {
Kiev,
Kharkiv,
Chernobyl, // Pretend we can't change the enum - Chernobyl will always be here
Odesa,
Dnipro,
}
fn choose_city(place: &amp;UkrainePlaces) {
use UkrainePlaces::*;
match place {
Kiev =&gt; println!(&quot;You will live in Kiev&quot;),
Kharkiv =&gt; println!(&quot;You will live in Kharkiv&quot;),
Chernobyl =&gt; unreachable!(),
Odesa =&gt; println!(&quot;You will live in Odesa&quot;),
Dnipro =&gt; println!(&quot;You will live in Dnipro&quot;),
}
}
fn main() {
let user_input = UkrainePlaces::Kiev; // Pretend the user input is made from some other function. The user can't choose Chernobyl, no matter what
choose_city(&amp;user_input);
}
</code></pre></pre>
<p>This will print <code>You will live in Kiev</code>.</p>
<p><code>unreachable!()</code> is also nice for you to read because it reminds you that some part of the code is unreachable. You have to be sure that the code is actually unreachable though. If the compiler ever calls <code>unreachable!()</code>, the program will panic.</p>
<p>Also, if you ever have unreachable code that the compiler knows about, it will tell you. Here is a quick example:</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
let true_or_false = true;
match true_or_false {
true =&gt; println!(&quot;It's true&quot;),
false =&gt; println!(&quot;It's false&quot;),
true =&gt; println!(&quot;It's true&quot;), // Whoops, we wrote true again
}
}
</code></pre></pre>
<p>It will say:</p>
<pre><code class="language-text">warning: unreachable pattern
--&gt; src/main.rs:7:9
|
7 | true =&gt; println!(&quot;It's true&quot;),
| ^^^^
|
</code></pre>
<p>But <code>unreachable!()</code> is for when the compiler can't know, like our other example.</p>
<p><code>column!</code>, <code>line!</code>, <code>file!</code>, <code>module_path!</code></p>
<p>These four macros are kind of like <code>dbg!()</code> because you just put them in to give you debug information. But they don't take any variables - you just use them with the brackets and nothing else. They are easy to learn together:</p>
<ul>
<li><code>column!()</code> gives you the column where you wrote it,</li>
<li><code>line!()</code> gives you the line where you wrote it, and</li>
<li><code>module_path!()</code> gives you the module where it is.</li>
</ul>
<p>The next code shows all three in a simple example. We will pretend there is a lot more code (mods inside mods), because that is why we would want to use these macros. You can imagine a big Rust program over many mods and files.</p>
<pre><pre class="playground"><code class="language-rust">pub mod something {
pub mod third_mod {
pub fn print_a_country(input: &amp;mut Vec&lt;&amp;str&gt;) {
println!(
&quot;The last country is {} inside the module {}&quot;,
input.pop().unwrap(),
module_path!()
);
}
}
}
fn main() {
use something::third_mod::*;
let mut country_vec = vec![&quot;Portugal&quot;, &quot;Czechia&quot;, &quot;Finland&quot;];
// do some stuff
println!(
&quot;On line {} we got the country {}&quot;,
line!(),
country_vec.pop().unwrap()
);
// do some more stuff
println!(
&quot;The next country is {} on line {} and column {}.&quot;,
country_vec.pop().unwrap(),
line!(),
column!(),
);
// lots more code
print_a_country(&amp;mut country_vec);
}
</code></pre></pre>
<p>It prints this:</p>
<pre><code class="language-text">On line 20 we got the country Finland
The next country is Czechia on line 29 and column 9.
The last country is Portugal inside the module rust_book::something::third_mod
</code></pre>
<p><code>cfg!</code></p>
<p>We know that you can use attributes like <code>#[cfg(test)]</code> and <code>#[cfg(windows)]</code> to tell the compiler what to do in certain cases. When you have <code>test</code>, it will run the code when you run Rust under testing mode (if it's on your computer you type <code>cargo test</code>). And when you use <code>windows</code>, it will run the code if the user is using Windows. But maybe you just want to change one tiny bit of code depending on the operating system, etc. That's when this macro is useful. It returns a <code>bool</code>.</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
let helpful_message = if cfg!(windows) { &quot;backslash&quot; } else { &quot;slash&quot; };
println!(
&quot;...then in your hard drive, type the directory name followed by a {}. Then you...&quot;,
helpful_message
);
}
</code></pre></pre>
<p>This will print differently, depending on your system. The Rust Playground runs on Linux, so it will print:</p>
<pre><code class="language-text">...then in your hard drive, type the directory name followed by a slash. Then you...
</code></pre>
<p><code>cfg!()</code> works for any kind of configuration. Here is an example of a function that runs differently when you use it inside a test.</p>
<pre><pre class="playground"><code class="language-rust">#[cfg(test)] // cfg! will know to look for the word test
mod testing {
use super::*;
#[test]
fn check_if_five() {
assert_eq!(bring_number(true), 5); // This bring_number() function should return 5
}
}
fn bring_number(should_run: bool) -&gt; u32 { // This function takes a bool as to whether it should run
if cfg!(test) &amp;&amp; should_run { // if it should run and has the configuration test, return 5
5
} else if should_run { // if it's not a test but it should run, print something. When you run a test it ignores println! statements
println!(&quot;Returning 5. This is not a test&quot;);
5
} else {
println!(&quot;This shouldn't run, returning 0.&quot;); // otherwise return 0
0
}
}
fn main() {
bring_number(true);
bring_number(false);
}
</code></pre></pre>
<p>Now it will run differently depending on the configuration. If you just run the program, it will give you this:</p>
<pre><code class="language-text">Returning 5. This is not a test
This shouldn't run, returning 0.
</code></pre>
<p>But if you run it in test mode (<code>cargo test</code> for Rust on your computer), it will actually run the test. And because the test always returns 5 in this case, it will pass.</p>
<pre><code class="language-text">running 1 test
test testing::check_if_five ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
</code></pre>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="Chapter_62.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_64.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_62.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_64.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>