easy_rust/Chapter_63.html
2021-05-23 04:18:41 +00:00

473 lines
29 KiB
HTML

<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title> Taking user input - Easy Rust</title>
<!-- Custom HTML head -->
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
<link rel="icon" href="favicon.svg">
<link rel="shortcut icon" href="favicon.png">
<link rel="stylesheet" href="css/variables.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/chrome.css">
<link rel="stylesheet" href="css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
</head>
<body>
<!-- Provide site root to javascript -->
<script type="text/javascript">
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded "><a href="Chapter_0.html"><strong aria-hidden="true">1.</strong> Updates</a></li><li class="chapter-item expanded "><a href="Chapter_1.html"><strong aria-hidden="true">2.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="Chapter_2.html"><strong aria-hidden="true">3.</strong> Who am I?</a></li><li class="chapter-item expanded "><a href="Chapter_3.html"><strong aria-hidden="true">4.</strong> Writing Rust in Easy English</a></li><li class="chapter-item expanded "><a href="Chapter_4.html"><strong aria-hidden="true">5.</strong> Rust Playground</a></li><li class="chapter-item expanded "><a href="Chapter_5.html"><strong aria-hidden="true">6.</strong> 🚧 and ⚠️</a></li><li class="chapter-item expanded "><a href="Chapter_6.html"><strong aria-hidden="true">7.</strong> Comments</a></li><li class="chapter-item expanded "><a href="Chapter_7.html"><strong aria-hidden="true">8.</strong> Types</a></li><li class="chapter-item expanded "><a href="Chapter_8.html"><strong aria-hidden="true">9.</strong> Type inference</a></li><li class="chapter-item expanded "><a href="Chapter_9.html"><strong aria-hidden="true">10.</strong> Printing 'hello, world!'</a></li><li class="chapter-item expanded "><a href="Chapter_10.html"><strong aria-hidden="true">11.</strong> Display and debug</a></li><li class="chapter-item expanded "><a href="Chapter_11.html"><strong aria-hidden="true">12.</strong> Mutability (changing)</a></li><li class="chapter-item expanded "><a href="Chapter_12.html"><strong aria-hidden="true">13.</strong> The stack, the heap, and pointers</a></li><li class="chapter-item expanded "><a href="Chapter_13.html"><strong aria-hidden="true">14.</strong> More about printing</a></li><li class="chapter-item expanded "><a href="Chapter_14.html"><strong aria-hidden="true">15.</strong> Strings</a></li><li class="chapter-item expanded "><a href="Chapter_15.html"><strong aria-hidden="true">16.</strong> const and static</a></li><li class="chapter-item expanded "><a href="Chapter_16.html"><strong aria-hidden="true">17.</strong> More on references</a></li><li class="chapter-item expanded "><a href="Chapter_17.html"><strong aria-hidden="true">18.</strong> Mutable references</a></li><li class="chapter-item expanded "><a href="Chapter_18.html"><strong aria-hidden="true">19.</strong> Giving references to functions</a></li><li class="chapter-item expanded "><a href="Chapter_19.html"><strong aria-hidden="true">20.</strong> Copy types</a></li><li class="chapter-item expanded "><a href="Chapter_20.html"><strong aria-hidden="true">21.</strong> Collection types</a></li><li class="chapter-item expanded "><a href="Chapter_21.html"><strong aria-hidden="true">22.</strong> Vectors</a></li><li class="chapter-item expanded "><a href="Chapter_22.html"><strong aria-hidden="true">23.</strong> Tuples</a></li><li class="chapter-item expanded "><a href="Chapter_23.html"><strong aria-hidden="true">24.</strong> Control flow</a></li><li class="chapter-item expanded "><a href="Chapter_24.html"><strong aria-hidden="true">25.</strong> Structs</a></li><li class="chapter-item expanded "><a href="Chapter_25.html"><strong aria-hidden="true">26.</strong> Enums</a></li><li class="chapter-item expanded "><a href="Chapter_26.html"><strong aria-hidden="true">27.</strong> Loops</a></li><li class="chapter-item expanded "><a href="Chapter_27.html"><strong aria-hidden="true">28.</strong> Implementing structs and enums</a></li><li class="chapter-item expanded "><a href="Chapter_28.html"><strong aria-hidden="true">29.</strong> Destructuring</a></li><li class="chapter-item expanded "><a href="Chapter_29.html"><strong aria-hidden="true">30.</strong> References and the dot operator</a></li><li class="chapter-item expanded "><a href="Chapter_30.html"><strong aria-hidden="true">31.</strong> Generics</a></li><li class="chapter-item expanded "><a href="Chapter_31.html"><strong aria-hidden="true">32.</strong> Option and Result</a></li><li class="chapter-item expanded "><a href="Chapter_32.html"><strong aria-hidden="true">33.</strong> Other collections</a></li><li class="chapter-item expanded "><a href="Chapter_33.html"><strong aria-hidden="true">34.</strong> The ? operator</a></li><li class="chapter-item expanded "><a href="Chapter_34.html"><strong aria-hidden="true">35.</strong> Traits</a></li><li class="chapter-item expanded "><a href="Chapter_35.html"><strong aria-hidden="true">36.</strong> Chaining methods</a></li><li class="chapter-item expanded "><a href="Chapter_36.html"><strong aria-hidden="true">37.</strong> Iterators</a></li><li class="chapter-item expanded "><a href="Chapter_37.html"><strong aria-hidden="true">38.</strong> Closures</a></li><li class="chapter-item expanded "><a href="Chapter_38.html"><strong aria-hidden="true">39.</strong> The dbg! macro and .inspect</a></li><li class="chapter-item expanded "><a href="Chapter_39.html"><strong aria-hidden="true">40.</strong> Types of &amp;str</a></li><li class="chapter-item expanded "><a href="Chapter_40.html"><strong aria-hidden="true">41.</strong> Lifetimes</a></li><li class="chapter-item expanded "><a href="Chapter_41.html"><strong aria-hidden="true">42.</strong> Interior mutability</a></li><li class="chapter-item expanded "><a href="Chapter_42.html"><strong aria-hidden="true">43.</strong> Cow</a></li><li class="chapter-item expanded "><a href="Chapter_43.html"><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" class="active"><strong aria-hidden="true">64.</strong> Taking user input</a></li><li class="chapter-item expanded "><a href="Chapter_64.html"><strong aria-hidden="true">65.</strong> Using files</a></li><li class="chapter-item expanded "><a href="Chapter_65.html"><strong aria-hidden="true">66.</strong> cargo doc</a></li><li class="chapter-item expanded "><a href="Chapter_66.html"><strong aria-hidden="true">67.</strong> The end?</a></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky bordered">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Easy Rust</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script type="text/javascript">
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h2 id="taking-user-input"><a class="header" href="#taking-user-input">Taking user input</a></h2>
<p>One easy way to take input from the user is with <code>std::io::stdin</code>. This means &quot;standard in&quot;, which is the input from the keyboard. With <code>stdin()</code> you can get user input, but then you will want to put it in a <code>&amp;mut String</code> with <code>.read_line()</code>. Here is a simple example of that, but it both works and doesn't work:</p>
<pre><pre class="playground"><code class="language-rust">use std::io;
fn main() {
println!(&quot;Please type something, or x to escape:&quot;);
let mut input_string = String::new();
while input_string != &quot;x&quot; { // This is the part that doesn't work right
input_string.clear(); // First clear the String. Otherwise it will keep adding to it
io::stdin().read_line(&amp;mut input_string).unwrap(); // Get the stdin from the user, and put it in read_string
println!(&quot;You wrote {}&quot;, input_string);
}
println!(&quot;See you later!&quot;);
}
</code></pre></pre>
<p>Here is what an output output looks like:</p>
<pre><code class="language-text">Please type something, or x to escape:
something
You wrote something
Something else
You wrote Something else
x
You wrote x
x
You wrote x
x
You wrote x
</code></pre>
<p>It takes our input and gives it back, and it even knows that we typed <code>x</code>. But it doesn't exit the program. The only way to get out is to close the window, or type ctrl and c. Let's change the <code>{}</code> to <code>{:?}</code> in <code>println!</code> to get more information (or you could use <code>dbg!(&amp;input_string)</code> if you like that macro). Now it says:</p>
<pre><code class="language-text">Please type something, or x to escape:
something
You wrote &quot;something\r\n&quot;
Something else
You wrote &quot;Something else\r\n&quot;
x
You wrote &quot;x\r\n&quot;
x
You wrote &quot;x\r\n&quot;
</code></pre>
<p>This is because the keyboard input is actually not just <code>something</code>, it is <code>something</code> and the <code>Enter</code> key. There is an easy method to fix this called <code>.trim()</code>, which removes all the whitespace. Whitespace, by the way, is all <a href="https://doc.rust-lang.org/reference/whitespace.html">these characters</a>:</p>
<pre><code class="language-text">U+0009 (horizontal tab, '\t')
U+000A (line feed, '\n')
U+000B (vertical tab)
U+000C (form feed)
U+000D (carriage return, '\r')
U+0020 (space, ' ')
U+0085 (next line)
U+200E (left-to-right mark)
U+200F (right-to-left mark)
U+2028 (line separator)
U+2029 (paragraph separator)
</code></pre>
<p>So that will turn <code>x\r\n</code> into just <code>x</code>. Now it works:</p>
<pre><pre class="playground"><code class="language-rust">use std::io;
fn main() {
println!(&quot;Please type something, or x to escape:&quot;);
let mut input_string = String::new();
while input_string.trim() != &quot;x&quot; {
input_string.clear();
io::stdin().read_line(&amp;mut input_string).unwrap();
println!(&quot;You wrote {}&quot;, input_string);
}
println!(&quot;See you later!&quot;);
}
</code></pre></pre>
<p>Now it will print:</p>
<pre><code class="language-text">Please type something, or x to escape:
something
You wrote something
Something
You wrote Something
x
You wrote x
See you later!
</code></pre>
<p>There is another kind of user input called <code>std::env::Args</code> (env means environment). <code>Args</code> is what the user types when starting the program. There is actually always at least one <code>Arg</code> in a program. Let's write a program that only prints them using <code>std::env::args()</code> to see what they are.</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
println!(&quot;{:?}&quot;, std::env::args());
}
</code></pre></pre>
<p>If we write <code>cargo run</code> then it prints something like this:</p>
<pre><code class="language-text">Args { inner: [&quot;target\\debug\\rust_book.exe&quot;] }
</code></pre>
<p>Let's give it more input and see what it does. We'll type <code>cargo run but with some extra words</code>. It gives us:</p>
<pre><code class="language-text">Args { inner: [&quot;target\\debug\\rust_book.exe&quot;, &quot;but&quot;, &quot;with&quot;, &quot;some&quot;, &quot;extra&quot;, &quot;words&quot;] }
</code></pre>
<p>Interesting. And when we look at <a href="https://doc.rust-lang.org/std/env/struct.Args.html">the page for Args</a>, we see that it implements <code>IntoIterator</code>. That means we can do all the things we know about iterators to read and change it. Let's try this:</p>
<pre><pre class="playground"><code class="language-rust">use std::env::args;
fn main() {
let input = args();
for entry in input {
println!(&quot;You entered: {}&quot;, entry);
}
}
</code></pre></pre>
<p>Now it says:</p>
<pre><code class="language-text">You entered: target\debug\rust_book.exe
You entered: but
You entered: with
You entered: some
You entered: extra
You entered: words
</code></pre>
<p>You can see that the first argument is always the program name, so you will often want to skip it, like this:</p>
<pre><pre class="playground"><code class="language-rust">use std::env::args;
fn main() {
let input = args();
input.skip(1).for_each(|item| {
println!(&quot;You wrote {}, which in capital letters is {}&quot;, item, item.to_uppercase());
})
}
</code></pre></pre>
<p>That will print:</p>
<pre><code class="language-text">You wrote but, which in capital letters is BUT
You wrote with, which in capital letters is WITH
You wrote some, which in capital letters is SOME
You wrote extra, which in capital letters is EXTRA
You wrote words, which in capital letters is WORDS
</code></pre>
<p>One common use for <code>Args</code> is for user settings. You can make sure that the user writes the input you need, and only run the program if it's right. Here's a small program that either makes letters big (capital) or small (lowercase):</p>
<pre><pre class="playground"><code class="language-rust">use std::env::args;
enum Letters {
Capitalize,
Lowercase,
Nothing,
}
fn main() {
let mut changes = Letters::Nothing;
let input = args().collect::&lt;Vec&lt;_&gt;&gt;();
if input.len() &gt; 2 {
match input[1].as_str() {
&quot;capital&quot; =&gt; changes = Letters::Capitalize,
&quot;lowercase&quot; =&gt; changes = Letters::Lowercase,
_ =&gt; {}
}
}
for word in input.iter().skip(2) {
match changes {
Letters::Capitalize =&gt; println!(&quot;{}&quot;, word.to_uppercase()),
Letters::Lowercase =&gt; println!(&quot;{}&quot;, word.to_lowercase()),
_ =&gt; println!(&quot;{}&quot;, word)
}
}
}
</code></pre></pre>
<p>Here are some examples of what it gives:</p>
<p>Input: <code>cargo run please make capitals</code>:</p>
<pre><code class="language-text">make capitals
</code></pre>
<p>Input: <code>cargo run capital</code>:</p>
<pre><code class="language-text">// Nothing here...
</code></pre>
<p>Input: <code>cargo run capital I think I understand now</code>:</p>
<pre><code class="language-text">I
THINK
I
UNDERSTAND
NOW
</code></pre>
<p>Input: <code>cargo run LOWERCASE Does this work too?</code></p>
<pre><code class="language-text">does
this
work
too?
</code></pre>
<p>Besides <code>Args</code> given by the user, available in <code>std::env::args()</code>, there are also <code>Vars</code> which are the system variables. Those are the basic settings for the program that the user didn't type in. You can use <code>std::env::vars()</code> to see them all as a <code>(String, String)</code>. There are very many. For example:</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
for item in std::env::vars() {
println!(&quot;{:?}&quot;, item);
}
}
</code></pre></pre>
<p>Just doing this shows you all the information about your user session. It will show information like this:</p>
<pre><code class="language-text">(&quot;CARGO&quot;, &quot;/playground/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/cargo&quot;)
(&quot;CARGO_HOME&quot;, &quot;/playground/.cargo&quot;)
(&quot;CARGO_MANIFEST_DIR&quot;, &quot;/playground&quot;)
(&quot;CARGO_PKG_AUTHORS&quot;, &quot;The Rust Playground&quot;)
(&quot;CARGO_PKG_DESCRIPTION&quot;, &quot;&quot;)
(&quot;CARGO_PKG_HOMEPAGE&quot;, &quot;&quot;)
(&quot;CARGO_PKG_NAME&quot;, &quot;playground&quot;)
(&quot;CARGO_PKG_REPOSITORY&quot;, &quot;&quot;)
(&quot;CARGO_PKG_VERSION&quot;, &quot;0.0.1&quot;)
(&quot;CARGO_PKG_VERSION_MAJOR&quot;, &quot;0&quot;)
(&quot;CARGO_PKG_VERSION_MINOR&quot;, &quot;0&quot;)
(&quot;CARGO_PKG_VERSION_PATCH&quot;, &quot;1&quot;)
(&quot;CARGO_PKG_VERSION_PRE&quot;, &quot;&quot;)
(&quot;DEBIAN_FRONTEND&quot;, &quot;noninteractive&quot;)
(&quot;HOME&quot;, &quot;/playground&quot;)
(&quot;HOSTNAME&quot;, &quot;f94c15b8134b&quot;)
(&quot;LD_LIBRARY_PATH&quot;, &quot;/playground/target/debug/build/backtrace-sys-3ec4c973f371c302/out:/playground/target/debug/build/libsqlite3-sys-fbddfbb9b241dacb/out:/playground/target/debug/build/ring-cadba5e583648abb/out:/playground/target/debug/deps:/playground/target/debug:/playground/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib:/playground/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib&quot;)
(&quot;PATH&quot;, &quot;/playground/.cargo/bin:/playground/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin&quot;)
(&quot;PLAYGROUND_EDITION&quot;, &quot;2018&quot;)
(&quot;PLAYGROUND_TIMEOUT&quot;, &quot;10&quot;)
(&quot;PWD&quot;, &quot;/playground&quot;)
(&quot;RUSTUP_HOME&quot;, &quot;/playground/.rustup&quot;)
(&quot;RUSTUP_TOOLCHAIN&quot;, &quot;stable-x86_64-unknown-linux-gnu&quot;)
(&quot;RUST_RECURSION_COUNT&quot;, &quot;1&quot;)
(&quot;SHLVL&quot;, &quot;1&quot;)
(&quot;SSL_CERT_DIR&quot;, &quot;/usr/lib/ssl/certs&quot;)
(&quot;SSL_CERT_FILE&quot;, &quot;/usr/lib/ssl/certs/ca-certificates.crt&quot;)
(&quot;USER&quot;, &quot;playground&quot;)
(&quot;_&quot;, &quot;/usr/bin/timeout&quot;)
</code></pre>
<p>So if you need this information, <code>Vars</code> is what you want.</p>
<p>The easiest way to get a single <code>Var</code> is by using the <code>env!</code> macro. You just give it the name of the variable, and it will give you a <code>&amp;str</code> with the value. It won't work if the variable is spelled wrong or does not exist, so if you aren't sure then use <code>option_env!</code> instead. If we write this on the Playground:</p>
<pre><pre class="playground"><code class="language-rust">fn main() {
println!(&quot;{}&quot;, env!(&quot;USER&quot;));
println!(&quot;{}&quot;, option_env!(&quot;ROOT&quot;).unwrap_or(&quot;Can't find ROOT&quot;));
println!(&quot;{}&quot;, option_env!(&quot;CARGO&quot;).unwrap_or(&quot;Can't find CARGO&quot;));
}
</code></pre></pre>
<p>then we get the output:</p>
<pre><code class="language-text">playground
Can't find ROOT
/playground/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/bin/cargo
</code></pre>
<p>So <code>option_env!</code> is always going to be the safer macro. <code>env!</code> is better if you actually want the program to crash when you can't find the environment variable.</p>
</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>