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

291 lines
30 KiB

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>An Introduction to Rust</title>
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
{ counter-reset: source-line 0; }
pre.numberSource code > span
{ position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::before
{ content: counter(source-line);
position: relative; left: -1em; text-align: right; vertical-align: baseline;
border: none; display: inline-block;
-webkit-touch-callout: none; -webkit-user-select: none;
-khtml-user-select: none; -moz-user-select: none;
-ms-user-select: none; user-select: none;
padding: 0 4px; width: 4em;
color: #aaaaaa;
}
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
div.sourceCode
{ }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
</style>
<link rel="stylesheet" href="./styles.css" />
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
<![endif]-->
</head>
<body>
<header id="title-block-header">
<h1 class="title">An Introduction to Rust</h1>
<p class="subtitle">if you don’t know systems programming</p>
</header>
<p><img alt="Ferris, an orange spiky crab, gesturing hello" src="ferris.png" width=300></p>
<h2 id="why-rust">Why Rust?</h2>
<p>Rust is a fast and memory-safe programming language with a strong type system and declarative memory management. It’s very focused on letting you write correct code, but can be hard to learn because of the restrictions it imposes to ensure this.</p>
<p>Rust also has really good error messages, well-written documentation, and excellent tools that make writing code and debugging easier. I like it because it helps me make sure that my program is doing exactly what I want it to. I hope you like it too!</p>
<h2 id="getting-started">Getting started</h2>
<p><strong>Where do I write Rust?</strong> Rust has two language servers that attach to your editor to analyze your code while you write it, <code>rls</code> and <code>rust-analyzer</code> (most people use the second). If you’re not already attached to a text editor, VS Code’s <code>rust-analyzer</code> extension is really good!</p>
<p><strong>Where do I find documentation?</strong> Documentation for Rust’s standard library is at <a href="https://doc.rust-lang.org/std/index.html" class="uri">https://doc.rust-lang.org/std/index.html</a>. Documentation for crates like macroquad is at <a href="#" class="uri">https://docs.rs/crate_name</a>.</p>
<p><strong>What’s cargo?</strong> Cargo is Rust’s package manager and build system. It downloads crates from <a href="https://crates.io" class="uri">https://crates.io</a>, runs projects, runs tests, generates documentation, manages dependencies, and more! You use it from the terminal—if you’re not familiar with it, there’s a tutorial linked on the last page.</p>
<h2 id="an-example">An example</h2>
<p>I’m going to walk through an example of an extremely minimal 2D game using the library Macroquad. First, you want to make a new crate (a project) with cargo. In the terminal, navigate to the folder where you want to make your project, and run the command:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1"></a><span class="ex">cargo</span> new --bin cool-game</span></code></pre></div>
<p>This will create a new folder in that directory, <code>cool-game</code>. It will contain a <code>src/</code> directory, where your Rust files will go, and a Cargo.toml file, where you’ll list the dependencies of the crate—in this case, just Macroquad (version 0.3.10).</p>
<p>At the end of the file, under [dependencies], add:</p>
<pre><code>macroquad = &quot;0.3.10&quot;</code></pre>
<p>and save the file.</p>
<p>Now, open the <code>main.rs</code> file in the <code>src/</code> folder and replace its contents with some setup code for Macroquad, taken from its documentation page: <a href="https://docs.rs/macroquad/0.3.10" class="uri">https://docs.rs/macroquad/0.3.10</a></p>
<div class="sourceCode" id="cb3"><pre class="sourceCode rust"><code class="sourceCode rust"><span id="cb3-1"><a href="#cb3-1"></a><span class="kw">use</span> <span class="pp">macroquad::prelude::</span><span class="op">*;</span> <span class="co">// A</span></span>
<span id="cb3-2"><a href="#cb3-2"></a></span>
<span id="cb3-3"><a href="#cb3-3"></a><span class="at">#[</span><span class="pp">macroquad::</span>main<span class="at">(</span><span class="st">&quot;cool game&quot;</span><span class="at">)]</span> <span class="co">// B</span></span>
<span id="cb3-4"><a href="#cb3-4"></a><span class="kw">async</span> <span class="kw">fn</span> main() <span class="op">{</span> <span class="co">// C</span></span>
<span id="cb3-5"><a href="#cb3-5"></a> <span class="kw">loop</span> <span class="op">{</span></span>
<span id="cb3-6"><a href="#cb3-6"></a> next_frame()<span class="op">.</span><span class="kw">await</span><span class="op">;</span> <span class="co">// C</span></span>
<span id="cb3-7"><a href="#cb3-7"></a> <span class="op">}</span></span>
<span id="cb3-8"><a href="#cb3-8"></a><span class="op">}</span></span></code></pre></div>
<ul>
<li>A: import Macroquad’s functions to this file</li>
<li>B: a macro/attribute that tells Macroquad what the title of the game is, and to use the function below to run the game</li>
<li>C: Macroquad uses async/await to let its games run in the browser, but you don’t need to worry about it here</li>
</ul>
<p>You can run this from the terminal with the command <code>cargo run</code>, and a window with a black background should pop up.This isn’t particularly interesting, but Macroquad provides functions we can draw with:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode rust"><code class="sourceCode rust"><span id="cb4-1"><a href="#cb4-1"></a><span class="kw">loop</span> <span class="op">{</span></span>
<span id="cb4-2"><a href="#cb4-2"></a> clear_background(DARKBLUE)<span class="op">;</span></span>
<span id="cb4-3"><a href="#cb4-3"></a> draw_rectangle(<span class="dv">350.0</span><span class="op">,</span> <span class="dv">250.0</span><span class="op">,</span> <span class="dv">100.0</span><span class="op">,</span> <span class="dv">100.0</span><span class="op">,</span> PINK)<span class="op">;</span></span>
<span id="cb4-4"><a href="#cb4-4"></a> next_frame()<span class="op">.</span><span class="kw">await</span><span class="op">;</span></span>
<span id="cb4-5"><a href="#cb4-5"></a><span class="op">}</span></span></code></pre></div>
<p>Now when we run this there’ll be a blue background and a pink square in the middle.</p>
<h2 id="a-tour-of-some-basic-syntax">A tour of some basic syntax</h2>
<p>We can add an if statement at the beginning of the loop to break out of it (then close the window) when the player presses the Q key:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode rust"><code class="sourceCode rust"><span id="cb5-1"><a href="#cb5-1"></a><span class="kw">if</span> is_key_down(<span class="pp">KeyCode::</span>Q) <span class="op">{</span> <span class="co">// A, B</span></span>
<span id="cb5-2"><a href="#cb5-2"></a> <span class="pp">println!</span>(<span class="st">&quot;thanks for playing!&quot;</span>)<span class="op">;</span> <span class="co">// C</span></span>
<span id="cb5-3"><a href="#cb5-3"></a> <span class="kw">break</span><span class="op">;</span></span>
<span id="cb5-4"><a href="#cb5-4"></a><span class="op">}</span></span></code></pre></div>
<ul>
<li>A: no parentheses needed around the condition</li>
<li>B: A keycode is an enum, or a type that can be one of several variants. For example, defining an <code>enum Pet { Cat, Dog }</code> allows you to say that your pet is a <code>Pet::Cat</code> or a <code>Pet::Dog</code>, but nothing else.</li>
<li>C: <code>println!</code> is a macro (you can tell because of the !) used to format and print things to the console</li>
</ul>
<h2 id="what-about-drawing-many-things">What about drawing many things?</h2>
<p>Here’s a for loop:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode rust"><code class="sourceCode rust"><span id="cb6-1"><a href="#cb6-1"></a><span class="kw">for</span> i <span class="kw">in</span> <span class="dv">0</span><span class="op">..</span><span class="dv">5</span> <span class="op">{</span> <span class="co">// A</span></span>
<span id="cb6-2"><a href="#cb6-2"></a> draw_rectangle(</span>
<span id="cb6-3"><a href="#cb6-3"></a> <span class="dv">150.0</span> <span class="op">*</span> i <span class="kw">as</span> <span class="dt">f32</span><span class="op">,</span> <span class="co">// B</span></span>
<span id="cb6-4"><a href="#cb6-4"></a> <span class="dv">250.0</span><span class="op">,</span> <span class="dv">100.0</span><span class="op">,</span> <span class="dv">100.0</span><span class="op">,</span> PINK</span>
<span id="cb6-5"><a href="#cb6-5"></a> )<span class="op">;</span></span>
<span id="cb6-6"><a href="#cb6-6"></a><span class="op">}</span></span></code></pre></div>
<ul>
<li>A: a range from 0 to 5 (not including 5)</li>
<li>B: <code>i</code> is an integer, so we use <code>as</code> to cast between number types (floats to integers, etc)</li>
</ul>
<p>You can iterate over a range or a collection.</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode rust"><code class="sourceCode rust"><span id="cb7-1"><a href="#cb7-1"></a><span class="kw">let</span> positions <span class="op">=</span> <span class="pp">vec!</span>[<span class="dv">100.0</span><span class="op">,</span> <span class="dv">250.0</span><span class="op">,</span> <span class="dv">400.0</span><span class="op">,</span> <span class="dv">550.0</span>]<span class="op">;</span> <span class="co">// A, B</span></span>
<span id="cb7-2"><a href="#cb7-2"></a></span>
<span id="cb7-3"><a href="#cb7-3"></a><span class="kw">for</span> x <span class="kw">in</span> positions<span class="op">.</span>iter() <span class="op">{</span></span>
<span id="cb7-4"><a href="#cb7-4"></a> draw_rectangle(x<span class="op">,</span> <span class="dv">250.0</span><span class="op">,</span> <span class="dv">100.0</span><span class="op">,</span> <span class="dv">100.0</span><span class="op">,</span> PINK)<span class="op">;</span></span>
<span id="cb7-5"><a href="#cb7-5"></a><span class="op">}</span></span></code></pre></div>
<ul>
<li>A: declare variables with <code>let</code>. You don’t need to say what type it is unless it’s ambiguous (if the compiler gets confused and tells you to)</li>
<li>B: <code>vec!</code> is a macro that gives a shorthand to declare <code>Vec</code>s, which are like arrays</li>
</ul>
<h2 id="there-are-always-options">There are always options</h2>
<p>Rust doesn’t allow null variables, and you have to define what value a variable holds before using it. For example, this won’t compile:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode rust"><code class="sourceCode rust"><span id="cb8-1"><a href="#cb8-1"></a><span class="kw">let</span> positions<span class="op">;</span></span>
<span id="cb8-2"><a href="#cb8-2"></a><span class="kw">for</span> x <span class="kw">in</span> positions <span class="op">{</span></span>
<span id="cb8-3"><a href="#cb8-3"></a> draw_rectangle(x<span class="op">,</span> <span class="dv">250.0</span><span class="op">,</span> <span class="dv">100.0</span><span class="op">,</span> <span class="dv">100.0</span><span class="op">,</span> PINK)<span class="op">;</span></span>
<span id="cb8-4"><a href="#cb8-4"></a><span class="op">}</span></span></code></pre></div>
<p>If you want a variable to maybe hold a value, you can use the enum <code>Option</code>, and use a match statement to check if it’s <code>Some(value)</code> or <code>None</code>.</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode rust"><code class="sourceCode rust"><span id="cb9-1"><a href="#cb9-1"></a><span class="kw">let</span> maybe_positions <span class="op">=</span> <span class="cn">Some</span>(<span class="pp">vec!</span>[<span class="dv">100.0</span><span class="op">,</span> <span class="dv">250.0</span><span class="op">,</span> <span class="dv">400.0</span><span class="op">,</span> <span class="dv">550.0</span>])<span class="op">;</span></span>
<span id="cb9-2"><a href="#cb9-2"></a></span>
<span id="cb9-3"><a href="#cb9-3"></a><span class="kw">match</span> maybe_positions <span class="op">{</span> <span class="co">// A</span></span>
<span id="cb9-4"><a href="#cb9-4"></a> <span class="cn">Some</span>(positions) <span class="op">=&gt;</span> <span class="op">{</span></span>
<span id="cb9-5"><a href="#cb9-5"></a> <span class="co">// loop through the x positions in rects</span></span>
<span id="cb9-6"><a href="#cb9-6"></a> <span class="kw">for</span> x <span class="kw">in</span> positions <span class="op">{</span></span>
<span id="cb9-7"><a href="#cb9-7"></a> draw_rectangle(x<span class="op">,</span> <span class="dv">250.0</span><span class="op">,</span> <span class="dv">100.0</span><span class="op">,</span> <span class="dv">100.0</span><span class="op">,</span> PINK)<span class="op">;</span></span>
<span id="cb9-8"><a href="#cb9-8"></a> <span class="op">}</span></span>
<span id="cb9-9"><a href="#cb9-9"></a> <span class="op">},</span></span>
<span id="cb9-10"><a href="#cb9-10"></a> <span class="cn">None</span> <span class="op">=&gt;</span> <span class="op">{</span> <span class="co">/* do nothing */</span> <span class="op">}</span></span>
<span id="cb9-11"><a href="#cb9-11"></a><span class="op">}</span></span></code></pre></div>
<ul>
<li>A: a match statement is an if statement that compares one variable against the values on its branches. Often it’s used to check what variant of an enum a variable is, but can also match on other types like numbers or strings.</li>
</ul>
<h2 id="data-structures">Data Structures</h2>
<p>Games are usually interactive, so let’s make a player character. We can define a struct—like a Java/Python class—to hold data about our game.</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode rust"><code class="sourceCode rust"><span id="cb10-1"><a href="#cb10-1"></a><span class="kw">struct</span> Game <span class="op">{</span></span>
<span id="cb10-2"><a href="#cb10-2"></a> player<span class="op">:</span> Rect<span class="op">,</span> <span class="co">// A</span></span>
<span id="cb10-3"><a href="#cb10-3"></a><span class="op">}</span></span></code></pre></div>
<ul>
<li>A: Macroquad gives us the type <code>Rect</code>, which has an x and y position, a width, and a height</li>
</ul>
<p>We can implement functions for our <code>Game</code> with an <code>impl</code> block.</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode rust"><code class="sourceCode rust"><span id="cb11-1"><a href="#cb11-1"></a><span class="kw">impl</span> Game <span class="op">{</span></span>
<span id="cb11-2"><a href="#cb11-2"></a> <span class="kw">fn</span> new() <span class="op">-&gt;</span> <span class="dt">Self</span> <span class="op">{</span> <span class="co">// A</span></span>
<span id="cb11-3"><a href="#cb11-3"></a> <span class="dt">Self</span> <span class="op">{</span> player<span class="op">:</span> <span class="pp">Rect::</span>new(<span class="dv">50.0</span><span class="op">,</span> <span class="dv">50.0</span><span class="op">,</span> <span class="dv">25.0</span><span class="op">,</span> <span class="dv">25.0</span>) <span class="op">}</span> <span class="co">// B</span></span>
<span id="cb11-4"><a href="#cb11-4"></a> <span class="op">}</span></span>
<span id="cb11-5"><a href="#cb11-5"></a></span>
<span id="cb11-6"><a href="#cb11-6"></a> <span class="kw">fn</span> update(<span class="op">&amp;</span><span class="kw">mut</span> <span class="kw">self</span>) <span class="op">{</span></span>
<span id="cb11-7"><a href="#cb11-7"></a> <span class="kw">if</span> is_key_down(<span class="pp">KeyCode::</span>Up) <span class="op">{</span></span>
<span id="cb11-8"><a href="#cb11-8"></a> <span class="kw">self</span><span class="op">.</span>player<span class="op">.</span>y <span class="op">-=</span> <span class="dv">1.0</span><span class="op">;</span></span>
<span id="cb11-9"><a href="#cb11-9"></a> <span class="op">}</span></span>
<span id="cb11-10"><a href="#cb11-10"></a> <span class="kw">if</span> is_key_down(<span class="pp">KeyCode::</span>Down) <span class="op">{</span></span>
<span id="cb11-11"><a href="#cb11-11"></a> <span class="kw">self</span><span class="op">.</span>player<span class="op">.</span>y <span class="op">+=</span> <span class="dv">1.0</span><span class="op">;</span></span>
<span id="cb11-12"><a href="#cb11-12"></a> <span class="op">}</span></span>
<span id="cb11-13"><a href="#cb11-13"></a> <span class="kw">if</span> is_key_down(<span class="pp">KeyCode::</span>Right) <span class="op">{</span></span>
<span id="cb11-14"><a href="#cb11-14"></a> <span class="kw">self</span><span class="op">.</span>player<span class="op">.</span>x <span class="op">+=</span> <span class="dv">1.0</span><span class="op">;</span></span>
<span id="cb11-15"><a href="#cb11-15"></a> <span class="op">}</span></span>
<span id="cb11-16"><a href="#cb11-16"></a> <span class="kw">if</span> is_key_down(<span class="pp">KeyCode::</span>Left) <span class="op">{</span></span>
<span id="cb11-17"><a href="#cb11-17"></a> <span class="kw">self</span><span class="op">.</span>player<span class="op">.</span>x <span class="op">-=</span> <span class="dv">1.0</span><span class="op">;</span></span>
<span id="cb11-18"><a href="#cb11-18"></a> <span class="op">}</span></span>
<span id="cb11-19"><a href="#cb11-19"></a> <span class="op">}</span></span>
<span id="cb11-20"><a href="#cb11-20"></a></span>
<span id="cb11-21"><a href="#cb11-21"></a> <span class="kw">fn</span> draw(<span class="op">&amp;</span><span class="kw">self</span>) <span class="op">{</span> <span class="co">// C</span></span>
<span id="cb11-22"><a href="#cb11-22"></a> clear_background(DARKBLUE)<span class="op">;</span></span>
<span id="cb11-23"><a href="#cb11-23"></a></span>
<span id="cb11-24"><a href="#cb11-24"></a> draw_rectangle(<span class="kw">self</span><span class="op">.</span>player<span class="op">.</span>x<span class="op">,</span> <span class="kw">self</span><span class="op">.</span>player<span class="op">.</span>y<span class="op">,</span> </span>
<span id="cb11-25"><a href="#cb11-25"></a> <span class="kw">self</span><span class="op">.</span>player<span class="op">.</span>w<span class="op">,</span> <span class="kw">self</span><span class="op">.</span>player<span class="op">.</span>h<span class="op">,</span> PINK)<span class="op">;</span></span>
<span id="cb11-26"><a href="#cb11-26"></a> <span class="op">}</span></span>
<span id="cb11-27"><a href="#cb11-27"></a><span class="op">}</span></span></code></pre></div>
<ul>
<li>A: <code>Self</code> is shorthand for the type of the impl block</li>
<li>B: <code>Rect::new(...)</code> creates a rectangle at (50, 50) with width 25 and height 25</li>
<li>C: no <code>this</code> like in Java; need to explicitly include <code>self</code> parameter like in Python</li>
</ul>
<p>Then replace the contents of our async main function with</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode rust"><code class="sourceCode rust"><span id="cb12-1"><a href="#cb12-1"></a><span class="kw">let</span> <span class="kw">mut</span> game <span class="op">=</span> <span class="pp">Game::</span>new()<span class="op">;</span> <span class="co">// A</span></span>
<span id="cb12-2"><a href="#cb12-2"></a><span class="kw">loop</span> <span class="op">{</span></span>
<span id="cb12-3"><a href="#cb12-3"></a> <span class="kw">if</span> is_key_down(<span class="pp">KeyCode::</span>Q) <span class="op">{</span></span>
<span id="cb12-4"><a href="#cb12-4"></a> <span class="pp">println!</span>(<span class="st">&quot;thanks for playing!&quot;</span>)<span class="op">;</span></span>
<span id="cb12-5"><a href="#cb12-5"></a> <span class="kw">break</span><span class="op">;</span></span>
<span id="cb12-6"><a href="#cb12-6"></a> <span class="op">}</span></span>
<span id="cb12-7"><a href="#cb12-7"></a> game<span class="op">.</span>draw()<span class="op">;</span> <span class="co">// B</span></span>
<span id="cb12-8"><a href="#cb12-8"></a> game<span class="op">.</span>update()<span class="op">;</span> <span class="co">// B</span></span>
<span id="cb12-9"><a href="#cb12-9"></a> next_frame()<span class="op">.</span><span class="kw">await</span><span class="op">;</span></span>
<span id="cb12-10"><a href="#cb12-10"></a><span class="op">}</span></span></code></pre></div>
<ul>
<li>A: if a function doesn’t have a <code>self</code> parameter, call it with <code>Type::function_name()</code></li>
<li>B: if it does, call it with a [.] (dot/period) on a variable of the type the function is implemented for</li>
</ul>
<p>And we’ll have a pink square on a blue background that we can move with arrow keys. Yay :)</p>
<h2 id="whats-up-with-the-mut-keyword">What’s up with the mut keyword?</h2>
<p>All variables in Rust are immutable by default, so we have to explicitly tell Rust that we want to be able to change it. This might seem weird and restrictive, but Rust is very cautious: it doesn’t want you accidentally modifying data that shouldn’t be changed.</p>
<p>Likewise, when defining our game’s update method, we had to add a mut keyword to let us modify the game state.</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode rust"><code class="sourceCode rust"><span id="cb13-1"><a href="#cb13-1"></a><span class="kw">fn</span> update(<span class="op">&amp;</span><span class="kw">mut</span> <span class="kw">self</span>) <span class="op">{</span> <span class="op">...</span> <span class="op">}</span></span></code></pre></div>
<p>But what about the <code>&amp;</code>?</p>
<h2 id="detour-ownership">Detour: Ownership</h2>
<p>Every value in Rust can only owned by a single variable. For example, if we try to assign our game to another variable,</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode rust"><code class="sourceCode rust"><span id="cb14-1"><a href="#cb14-1"></a><span class="kw">let</span> <span class="kw">mut</span> game <span class="op">=</span> <span class="pp">Game::</span>new()<span class="op">;</span></span>
<span id="cb14-2"><a href="#cb14-2"></a><span class="op">{</span></span>
<span id="cb14-3"><a href="#cb14-3"></a> <span class="kw">let</span> <span class="kw">mut</span> game2 <span class="op">=</span> game<span class="op">;</span></span>
<span id="cb14-4"><a href="#cb14-4"></a> <span class="co">// do things with game2</span></span>
<span id="cb14-5"><a href="#cb14-5"></a><span class="op">}</span></span>
<span id="cb14-6"><a href="#cb14-6"></a><span class="kw">loop</span> <span class="op">{</span></span>
<span id="cb14-7"><a href="#cb14-7"></a> game<span class="op">.</span>draw()<span class="op">;</span></span>
<span id="cb14-8"><a href="#cb14-8"></a> game<span class="op">.</span>update()<span class="op">;</span></span>
<span id="cb14-9"><a href="#cb14-9"></a><span class="op">}</span></span></code></pre></div>
<p>This won’t compile because the game now belongs to <code>game2</code> after assigning it again, so the first <code>game</code> is now invalid. Rust doesn’t want multiple variables to own the same data at the same time. This has to do with how memory management works in Rust, but I won’t get into that here (on the final page there are links to people who explain it far better than I could).</p>
<h2 id="borrowing">Borrowing</h2>
<p>But sometimes you want values to be accessible or modifiable from different locations. Here you would borrow <code>game</code> with a reference using the <code>&amp;</code> symbol, which points to the data at a variable without moving it.</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode rust"><code class="sourceCode rust"><span id="cb15-1"><a href="#cb15-1"></a><span class="kw">let</span> <span class="kw">mut</span> game <span class="op">=</span> <span class="pp">Game::</span>new()<span class="op">;</span></span>
<span id="cb15-2"><a href="#cb15-2"></a><span class="op">{</span></span>
<span id="cb15-3"><a href="#cb15-3"></a> <span class="kw">let</span> game2 <span class="op">=</span> <span class="op">&amp;</span>game<span class="op">;</span></span>
<span id="cb15-4"><a href="#cb15-4"></a> <span class="co">// do things with game2</span></span>
<span id="cb15-5"><a href="#cb15-5"></a><span class="op">}</span></span>
<span id="cb15-6"><a href="#cb15-6"></a><span class="co">// ...</span></span></code></pre></div>
<p>And this would compile! If you wanted to use <code>game2</code> to modify <code>game</code>, you would make the reference mutable:</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode rust"><code class="sourceCode rust"><span id="cb16-1"><a href="#cb16-1"></a><span class="kw">let</span> game2 <span class="op">=</span> <span class="op">&amp;</span><span class="kw">mut</span> game<span class="op">;</span></span></code></pre></div>
<p>You can have as many immutable references to the same value as you want, but only one mutable reference. Like ownership, Rust hates it when multiple things are able to modify the same data at the same time.</p>
<h2 id="rules-of-thumb">Rules of thumb</h2>
<p>Every value can only ever have either:</p>
<ol type="1">
<li>No borrows</li>
<li>One or more immutable references (&amp;)</li>
<li>Exactly one mutable reference (&amp;mut)</li>
</ol>
<p>(this list was stolen from CS181G (spring 2021) course notes by Prof Osborn. Thanks Prof Osborn)</p>
<p>Ownership and references are tricky concepts, so don’t worry if you don’t understand them at first. You’ll get it!</p>
<hr />
<p>Now you have a tiny game and know some basics of Rust. Congrats!</p>
<h2 id="pro-tips">Pro tips</h2>
<p>Read the error messages!</p>
<p>Be patient!</p>
<p>You’ll be okay!!</p>
<h2 id="resources">Resources</h2>
<ul>
<li>Rust book: <a href="https://doc.rust-lang.org/book/" class="uri">https://doc.rust-lang.org/book/</a></li>
<li>Rust documentation: <a href="https://doc.rust-lang.org/std/index.html" class="uri">https://doc.rust-lang.org/std/index.html</a></li>
<li>Crates (packages): <a href="https://crates.io" class="uri">https://crates.io</a></li>
<li>Crate documentation: <a href="https://docs.rs" class="uri">https://docs.rs</a></li>
<li>Terminal tutorials: <a href="https://blog.balthazar-rouberol.com/discovering-the-terminal" class="uri">https://blog.balthazar-rouberol.com/discovering-the-terminal</a>, <a href="https://www.learnshell.org/" class="uri">https://www.learnshell.org/</a>, <a href="https://coolguy.website/map-is-the-territory/introduction.html" class="uri">https://coolguy.website/map-is-the-territory/introduction.html</a></li>
<li>More in-depth explanations of ownership and references: <a href="https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html" class="uri">https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html</a>, <a href="https://www.youtube.com/watch?v=8M0QfLUDaaA" class="uri">https://www.youtube.com/watch?v=8M0QfLUDaaA</a> (no captions but good)</li>
</ul>
<h2 id="credits">Credits</h2>
<p>Ferris image from <a href="https://rustacean.net" class="uri">https://rustacean.net</a> // draws inspiration from the Rust book, Prof Osborn’s CS181G Rust intro notes, and Becca Turner’s RustConf 2020 talk</p>
<p>written by Cynthia Li // made with 🦀 💙</p>
</body>
</html>