<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Syam SV</title>
    <description>The latest articles on DEV Community by Syam SV (@syamsv).</description>
    <link>https://dev.to/syamsv</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1141401%2Fcaaca979-7fa7-452d-8f25-5a8fa560ca7d.jpg</url>
      <title>DEV Community: Syam SV</title>
      <link>https://dev.to/syamsv</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/syamsv"/>
    <language>en</language>
    <item>
      <title>Rust for Gophers, Lesson 3: Structs, Enums, and Match</title>
      <dc:creator>Syam SV</dc:creator>
      <pubDate>Wed, 28 Oct 2026 17:21:49 +0000</pubDate>
      <link>https://dev.to/syamsv/rust-for-gophers-lesson-3-structs-enums-and-match-3n2d</link>
      <guid>https://dev.to/syamsv/rust-for-gophers-lesson-3-structs-enums-and-match-3n2d</guid>
      <description>&lt;h2&gt;
  
  
  1. Structs
&lt;/h2&gt;

&lt;p&gt;Rust structs look like Go structs, with three differences that matter: there are no zero values, there is no embedding, and behaviour like printing or comparing is opted into with &lt;code&gt;derive&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[derive(Debug,&lt;/span&gt; &lt;span class="nd"&gt;Clone,&lt;/span&gt; &lt;span class="nd"&gt;PartialEq)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="c1"&gt;// owned: the struct owns its data (Lesson 2)&lt;/span&gt;
    &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;active&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;login_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"syam"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"s@x.dev"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;active&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;login_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="c1"&gt;// every field must be set; no implicit zero values&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;u2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ana"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;           &lt;span class="c1"&gt;// struct update syntax: take the remaining fields from another value&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;No zero values.&lt;/strong&gt; Go silently fills omitted fields with &lt;code&gt;0&lt;/code&gt;, &lt;code&gt;""&lt;/code&gt; or &lt;code&gt;nil&lt;/code&gt;. Rust makes you write every field, so adding a field to a struct turns every construction site into a compile error until you handle it. That's a refactoring safety net. When you do want defaults, opt in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[derive(Debug,&lt;/span&gt; &lt;span class="nd"&gt;Default)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Config&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;verbose&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Config&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="nn"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;  &lt;span class="c1"&gt;// the rest is 0 / false / ""&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Struct fields are almost always owned types&lt;/strong&gt; (&lt;code&gt;String&lt;/code&gt;, &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt;), not references. A struct holding &lt;code&gt;&amp;amp;str&lt;/code&gt; needs a lifetime annotation and can't outlive the data it borrows. That's sometimes right (Lesson 8), but owned fields are the default choice.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tuple structs and the newtype pattern
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[derive(Debug,&lt;/span&gt; &lt;span class="nd"&gt;Clone,&lt;/span&gt; &lt;span class="nd"&gt;Copy,&lt;/span&gt; &lt;span class="nd"&gt;PartialEq,&lt;/span&gt; &lt;span class="nd"&gt;PartialOrd)]&lt;/span&gt;
&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nf"&gt;Meters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;Meters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;raw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;         &lt;span class="c1"&gt;// fields are accessed by position&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wrapping a primitive in a one-field struct is called a &lt;strong&gt;newtype&lt;/strong&gt;. It costs nothing at runtime, but &lt;code&gt;Meters&lt;/code&gt; and &lt;code&gt;Feet&lt;/code&gt; (or &lt;code&gt;UserId&lt;/code&gt; and &lt;code&gt;OrderId&lt;/code&gt;) become different types the compiler won't mix up. Go's &lt;code&gt;type UserID int64&lt;/code&gt; is similar, but Go converts between them freely with &lt;code&gt;UserID(x)&lt;/code&gt;. Industry Rust uses newtypes heavily for IDs and validated values.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;derive&lt;/code&gt;: opting in to behaviour
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Derive&lt;/th&gt;
&lt;th&gt;Gives you&lt;/th&gt;
&lt;th&gt;Go equivalent&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Debug&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;{:?}&lt;/code&gt; printing&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;%v&lt;/code&gt; / &lt;code&gt;%+v&lt;/code&gt; (automatic in Go)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Clone&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;.clone()&lt;/code&gt; deep copy&lt;/td&gt;
&lt;td&gt;Manual copying&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Copy&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Implicit bitwise copy; only if every field is &lt;code&gt;Copy&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Value semantics for small structs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;PartialEq&lt;/code&gt;, &lt;code&gt;Eq&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;==&lt;/code&gt; and &lt;code&gt;!=&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;==&lt;/code&gt; on comparable structs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;PartialOrd&lt;/code&gt;, &lt;code&gt;Ord&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;&amp;lt;&lt;/code&gt;, &lt;code&gt;&amp;gt;&lt;/code&gt;, sorting&lt;/td&gt;
&lt;td&gt;No built-in equivalent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Hash&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Usable as a &lt;code&gt;HashMap&lt;/code&gt; key&lt;/td&gt;
&lt;td&gt;Map keys must be comparable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Default&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;T::default()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Zero values&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A good habit is to derive &lt;code&gt;Debug&lt;/code&gt; on every type, and &lt;code&gt;Clone&lt;/code&gt;/&lt;code&gt;PartialEq&lt;/code&gt; when they make sense. &lt;code&gt;Copy&lt;/code&gt; is only for small, plain-data types; never derive it on something that owns heap memory (the compiler won't let you anyway).&lt;/p&gt;

&lt;h2&gt;
  
  
  2. &lt;code&gt;impl&lt;/code&gt; blocks: methods and constructors
&lt;/h2&gt;

&lt;p&gt;Methods live in an &lt;code&gt;impl&lt;/code&gt; block separate from the struct definition, much like Go's &lt;code&gt;func (u *User) ...&lt;/code&gt; methods live outside the &lt;code&gt;type&lt;/code&gt; declaration. The difference is the receiver: Go has two kinds (value and pointer), Rust has three, and they are exactly the three ownership modes from Lesson 2.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Associated function (no self): Rust's constructor convention, like Go's NewUser&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="n"&gt;active&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;login_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;display_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;   &lt;span class="c1"&gt;// borrows self read-only&lt;/span&gt;
        &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.name&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;record_login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;       &lt;span class="c1"&gt;// borrows self exclusively, may modify&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.login_count&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;into_email&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;    &lt;span class="c1"&gt;// takes ownership; u is unusable afterwards&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.email&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;User&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"syam"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"s@x.dev"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// :: calls an associated function&lt;/span&gt;
&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="nf"&gt;.record_login&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;                            &lt;span class="c1"&gt;// . calls a method; &amp;amp;mut u is taken automatically&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="nf"&gt;.into_email&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;                  &lt;span class="c1"&gt;// u is moved here&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Receiver&lt;/th&gt;
&lt;th&gt;Go equivalent&lt;/th&gt;
&lt;th&gt;Use when&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;self&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;func (u User)&lt;/code&gt; or &lt;code&gt;func (u *User)&lt;/code&gt; that only reads&lt;/td&gt;
&lt;td&gt;Getters, computations. Most methods&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;mut self&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;func (u *User)&lt;/code&gt; that writes&lt;/td&gt;
&lt;td&gt;Changing state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;self&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No equivalent&lt;/td&gt;
&lt;td&gt;Consuming or converting: &lt;code&gt;into_*&lt;/code&gt; methods, builders&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Naming conventions you will see everywhere: &lt;code&gt;new&lt;/code&gt; for the main constructor, &lt;code&gt;with_*&lt;/code&gt; for alternatives (&lt;code&gt;Vec::with_capacity&lt;/code&gt;), &lt;code&gt;as_*&lt;/code&gt; for cheap borrowed views (&lt;code&gt;as_str&lt;/code&gt;), &lt;code&gt;to_*&lt;/code&gt; for expensive conversions that allocate (&lt;code&gt;to_string&lt;/code&gt;), and &lt;code&gt;into_*&lt;/code&gt; for conversions that consume &lt;code&gt;self&lt;/code&gt;. Getters are named after the field (&lt;code&gt;name()&lt;/code&gt;), never &lt;code&gt;get_name()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Self&lt;/code&gt; (capital S) is an alias for the type the &lt;code&gt;impl&lt;/code&gt; is for. Use it in constructors and return types so renaming the type later only touches one line.&lt;/p&gt;

&lt;p&gt;The method call &lt;code&gt;u.record_login()&lt;/code&gt; is sugar for &lt;code&gt;User::record_login(&amp;amp;mut u)&lt;/code&gt;. Rust auto-borrows the receiver, which is why you never write &lt;code&gt;(&amp;amp;mut u).record_login()&lt;/code&gt;. Go does the same thing when it takes &lt;code&gt;&amp;amp;u&lt;/code&gt; for pointer-receiver methods.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Enums: the feature Go doesn't have
&lt;/h2&gt;

&lt;p&gt;A Rust enum is a &lt;strong&gt;sum type&lt;/strong&gt;: a value that is exactly one of several variants, where each variant can carry its own data. This is the single feature Go programmers miss most once they've used it.&lt;/p&gt;

&lt;p&gt;The simple case looks like Go's &lt;code&gt;iota&lt;/code&gt; constants:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[derive(Debug,&lt;/span&gt; &lt;span class="nd"&gt;Clone,&lt;/span&gt; &lt;span class="nd"&gt;Copy,&lt;/span&gt; &lt;span class="nd"&gt;PartialEq,&lt;/span&gt; &lt;span class="nd"&gt;Eq)]&lt;/span&gt;
&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Active&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Suspended&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Deleted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The difference is that &lt;code&gt;Status&lt;/code&gt; is a real type. A Go &lt;code&gt;type Status int&lt;/code&gt; accepts &lt;code&gt;Status(42)&lt;/code&gt;, which is a status that doesn't exist. A Rust &lt;code&gt;Status&lt;/code&gt; can only ever be one of those three values.&lt;/p&gt;

&lt;p&gt;The powerful case is variants with data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;Shape&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Circle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;          &lt;span class="c1"&gt;// struct-like variant&lt;/span&gt;
    &lt;span class="n"&gt;Rect&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nf"&gt;Triangle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;         &lt;span class="c1"&gt;// tuple-like variant&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Shape&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;area&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nn"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Circle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;radius&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;consts&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;PI&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;radius&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nn"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Rect&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nn"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Triangle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="nf"&gt;.sqrt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How you would write this in Go:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Shape&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Area&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Circle&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Radius&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Rect&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;W&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;H&lt;/span&gt; &lt;span class="kt"&gt;float64&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c"&gt;// ... plus a type switch somewhere:&lt;/span&gt;
&lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;Circle&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;Rect&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="c"&gt;// forgot Triangle? compiles fine, silently does nothing&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Go interface + type switch&lt;/th&gt;
&lt;th&gt;Rust enum + &lt;code&gt;match&lt;/code&gt;
&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Set of variants&lt;/td&gt;
&lt;td&gt;Open: anyone can implement the interface&lt;/td&gt;
&lt;td&gt;Closed: exactly the variants listed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Missing a case&lt;/td&gt;
&lt;td&gt;Compiles; bug at runtime&lt;/td&gt;
&lt;td&gt;Compile error&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Can be nil&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory&lt;/td&gt;
&lt;td&gt;Usually boxed behind an interface pointer, often a heap allocation&lt;/td&gt;
&lt;td&gt;Stored inline: size of the largest variant plus a tag&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Rust also has the open kind of polymorphism (traits, Lesson 5). Use an enum when you know all the cases (tokens, commands, HTTP methods, states in a state machine, errors). Use a trait when other code needs to add new types. In real Rust code, enums are everywhere: &lt;code&gt;Option&lt;/code&gt;, &lt;code&gt;Result&lt;/code&gt;, JSON values, AST nodes, and the messages sent between threads.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt;: no more nil
&lt;/h2&gt;

&lt;p&gt;Rust has no &lt;code&gt;nil&lt;/code&gt;. A value that might be absent has the type &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt;, which is just an ordinary enum from the standard library:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nb"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The point is that &lt;code&gt;Option&amp;lt;User&amp;gt;&lt;/code&gt; and &lt;code&gt;User&lt;/code&gt; are different types. You cannot call &lt;code&gt;.name&lt;/code&gt; on an &lt;code&gt;Option&amp;lt;User&amp;gt;&lt;/code&gt;; you must first handle the &lt;code&gt;None&lt;/code&gt; case. So the Go bug "forgot to check for nil, panicked in production" becomes a compile error. And when a function returns plain &lt;code&gt;User&lt;/code&gt;, you know for certain it's there.&lt;/p&gt;

&lt;p&gt;It also costs nothing: &lt;code&gt;Option&amp;lt;&amp;amp;User&amp;gt;&lt;/code&gt; is the same size as &lt;code&gt;&amp;amp;User&lt;/code&gt;, because the compiler uses the impossible null address to represent &lt;code&gt;None&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;find_user&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;'a&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.find&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="py"&gt;.name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(The &lt;code&gt;&amp;lt;'a&amp;gt;&lt;/code&gt; is needed because there are two reference inputs, as in Drill 5. It says the returned reference borrows from &lt;code&gt;users&lt;/code&gt;, not from &lt;code&gt;name&lt;/code&gt;.)&lt;/p&gt;

&lt;h3&gt;
  
  
  Everyday ways to handle an &lt;code&gt;Option&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 1. match: handle both cases explicitly&lt;/span&gt;
&lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="nf"&gt;find_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"ana"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"found {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="py"&gt;.email&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nb"&gt;None&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"not found"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// 2. if let: you only care about the Some case&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;find_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"ana"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"found {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="py"&gt;.email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// 3. let else: unwrap or leave the function early (Go's `if x == nil { return }`)&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;find_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"ana"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// 4. Combinators: transform without unwrapping&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;find_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"zed"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="py"&gt;.name&lt;/span&gt;&lt;span class="nf"&gt;.as_str&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;   &lt;span class="c1"&gt;// Option&amp;lt;&amp;amp;User&amp;gt; -&amp;gt; Option&amp;lt;&amp;amp;str&amp;gt;&lt;/span&gt;
    &lt;span class="nf"&gt;.unwrap_or&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"nobody"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;       &lt;span class="c1"&gt;// fall back to a default&lt;/span&gt;

&lt;span class="c1"&gt;// 5. The ? operator: inside a function returning Option, return None early&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;first_even&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xs&lt;/span&gt;&lt;span class="nf"&gt;.first&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c1"&gt;// if None, return None from first_even right now&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;None&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Does&lt;/th&gt;
&lt;th&gt;Use it when&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;map(f)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Transforms the inner value if &lt;code&gt;Some&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Chaining a computation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;and_then(f)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Like &lt;code&gt;map&lt;/code&gt;, but &lt;code&gt;f&lt;/code&gt; returns an &lt;code&gt;Option&lt;/code&gt; itself&lt;/td&gt;
&lt;td&gt;Chaining steps that can each fail&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;unwrap_or(v)&lt;/code&gt; / &lt;code&gt;unwrap_or_default()&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Gives the value or a fallback&lt;/td&gt;
&lt;td&gt;A sensible default exists&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;unwrap_or_else(f)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Fallback computed lazily&lt;/td&gt;
&lt;td&gt;The fallback is expensive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ok_or(err)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Turns &lt;code&gt;Option&lt;/code&gt; into &lt;code&gt;Result&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Lesson 4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;is_some()&lt;/code&gt; / &lt;code&gt;is_none()&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Tests without taking the value&lt;/td&gt;
&lt;td&gt;Only for checks; prefer &lt;code&gt;if let&lt;/code&gt; when you'll use the value&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;copied()&lt;/code&gt; / &lt;code&gt;cloned()&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Option&amp;lt;&amp;amp;T&amp;gt;&lt;/code&gt; to &lt;code&gt;Option&amp;lt;T&amp;gt;&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Getting an owned value out of a lookup&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;unwrap()&lt;/code&gt; / &lt;code&gt;expect("why")&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Panics on &lt;code&gt;None&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Tests and genuinely impossible cases only&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;On &lt;code&gt;unwrap()&lt;/code&gt;:&lt;/strong&gt; in production code, treat it as a red flag. Each one is a potential panic. If you are certain it can't fail, use &lt;code&gt;expect("reason it can't fail")&lt;/code&gt; so the panic message explains your assumption. In reviews, I'll ask you to justify each one.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Pattern matching in depth
&lt;/h2&gt;

&lt;p&gt;A pattern describes the &lt;em&gt;shape&lt;/em&gt; of a value and pulls pieces out of it in one step. Patterns appear in &lt;code&gt;match&lt;/code&gt;, &lt;code&gt;if let&lt;/code&gt;, &lt;code&gt;let else&lt;/code&gt;, &lt;code&gt;while let&lt;/code&gt;, &lt;code&gt;let&lt;/code&gt;, and function parameters.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;Command&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Quit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Move&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nf"&gt;Say&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nn"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Quit&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"bye"&lt;/span&gt;&lt;span class="nf"&gt;.to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="nn"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Move&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"vertical {y}"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;        &lt;span class="c1"&gt;// literal inside a pattern&lt;/span&gt;
        &lt;span class="nn"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Move&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"diagonal {x}"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// match guard&lt;/span&gt;
        &lt;span class="nn"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Move&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"move {x},{y}"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nn"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Say&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Things to notice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Arms are checked top to bottom&lt;/strong&gt;, and the first match wins. Put specific patterns before general ones. The compiler warns about an arm that can never be reached.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Matching on &lt;code&gt;&amp;amp;Command&lt;/code&gt; gives references.&lt;/strong&gt; Because &lt;code&gt;cmd&lt;/code&gt; is a reference, &lt;code&gt;msg&lt;/code&gt; binds as &lt;code&gt;&amp;amp;String&lt;/code&gt;, not &lt;code&gt;String&lt;/code&gt;, so nothing is moved out of the borrowed value. This feature is called "default binding modes" and it's why you rarely write &lt;code&gt;&amp;amp;&lt;/code&gt; or &lt;code&gt;ref&lt;/code&gt; in patterns.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exhaustiveness is your refactoring tool.&lt;/strong&gt; Add a &lt;code&gt;Command::Jump&lt;/code&gt; variant, and every &lt;code&gt;match&lt;/code&gt; that doesn't handle it becomes a compile error that lists exactly where to update. Avoid a lazy &lt;code&gt;_ =&amp;gt;&lt;/code&gt; arm on your own enums, because it switches that check off.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The pattern toolbox
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"newborn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..=&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"toddler"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;// @ binds the value while testing a range&lt;/span&gt;
    &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..=&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"child"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="o"&gt;..=&lt;/span&gt;&lt;span class="mi"&gt;19&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"teen"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"adult"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"origin"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"anti-diagonal"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"x={x}"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;           &lt;span class="c1"&gt;// _ ignores a part&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;      &lt;span class="c1"&gt;// destructure a struct; .. ignores the rest&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;is_gone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;matches!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Suspended&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Deleted&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// bool from a pattern&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;if let&lt;/code&gt;, &lt;code&gt;let else&lt;/code&gt;, &lt;code&gt;while let&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nn"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Say&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;          &lt;span class="c1"&gt;// one variant you care about&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{msg}"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;args&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.nth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  &lt;span class="c1"&gt;// unwrap or exit: flat code, no nesting&lt;/span&gt;
    &lt;span class="nd"&gt;eprintln!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"usage: rpn &amp;lt;expr&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nn"&gt;process&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;stack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="nf"&gt;.pop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;         &lt;span class="c1"&gt;// loop until the pattern stops matching&lt;/span&gt;
    &lt;span class="nd"&gt;print!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{top} "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;                       &lt;span class="c1"&gt;// 3 2 1&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;let else&lt;/code&gt; is the closest thing to Go's guard-clause style (&lt;code&gt;if err != nil { return }&lt;/code&gt;). It keeps the happy path unindented, and the &lt;code&gt;else&lt;/code&gt; block must leave the scope (&lt;code&gt;return&lt;/code&gt;, &lt;code&gt;break&lt;/code&gt;, &lt;code&gt;continue&lt;/code&gt;, or &lt;code&gt;exit&lt;/code&gt;). Industry Rust uses it heavily at the top of functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Exercise: a stack, and an RPN calculator on top of it
&lt;/h2&gt;

&lt;p&gt;You'll build the stack data structure, then use it to evaluate Reverse Polish Notation, where the operator comes after its operands: &lt;code&gt;3 4 + 2 *&lt;/code&gt; means &lt;code&gt;(3 + 4) * 2&lt;/code&gt;. It's a classic stack problem, and it exercises structs, methods, enums with data, &lt;code&gt;match&lt;/code&gt; and &lt;code&gt;Option&lt;/code&gt; together.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo new rpn &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;rpn
cargo run &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="s2"&gt;"3 4 + 2 *"&lt;/span&gt;    &lt;span class="c"&gt;# 14&lt;/span&gt;
cargo run &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="s2"&gt;"10 2 -"&lt;/span&gt;       &lt;span class="c"&gt;# 8&lt;/span&gt;
cargo run &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="s2"&gt;"-3 4 *"&lt;/span&gt;       &lt;span class="c"&gt;# -12  (a negative number, not the operator)&lt;/span&gt;
cargo run &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="s2"&gt;"1 0 /"&lt;/span&gt;        &lt;span class="c"&gt;# stderr: error: invalid expression, exit 1&lt;/span&gt;
cargo run &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="s2"&gt;"1 +"&lt;/span&gt;          &lt;span class="c"&gt;# stderr: error: invalid expression, exit 1&lt;/span&gt;
cargo run                   &lt;span class="c"&gt;# stderr: usage: rpn "&amp;lt;expression&amp;gt;", exit 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How RPN evaluation works: read tokens left to right. A number gets pushed. An operator pops two values (the first pop is the &lt;strong&gt;right&lt;/strong&gt; operand), applies itself, and pushes the result. At the end, exactly one value must remain on the stack.&lt;/p&gt;

&lt;h3&gt;
  
  
  Part A: the stack
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] &lt;code&gt;struct Stack&lt;/code&gt; wrapping a &lt;code&gt;Vec&amp;lt;i64&amp;gt;&lt;/code&gt;, with &lt;code&gt;#[derive(Debug, Default)]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;[ ] Methods with the right receivers: &lt;code&gt;new() -&amp;gt; Self&lt;/code&gt;, &lt;code&gt;push(v: i64)&lt;/code&gt;, &lt;code&gt;pop() -&amp;gt; Option&amp;lt;i64&amp;gt;&lt;/code&gt;, &lt;code&gt;peek() -&amp;gt; Option&amp;lt;&amp;amp;i64&amp;gt;&lt;/code&gt;, &lt;code&gt;len() -&amp;gt; usize&lt;/code&gt;. Choosing &lt;code&gt;&amp;amp;self&lt;/code&gt; vs &lt;code&gt;&amp;amp;mut self&lt;/code&gt; for each is part of the exercise.&lt;/li&gt;
&lt;li&gt;[ ] Tests: pop on an empty stack, push then peek, and LIFO order after several pushes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Part B: the calculator
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] &lt;code&gt;enum Op { Add, Sub, Mul, Div }&lt;/code&gt; and &lt;code&gt;enum Token { Num(i64), Op(Op) }&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;fn parse_token(s: &amp;amp;str) -&amp;gt; Option&amp;lt;Token&amp;gt;&lt;/code&gt;, written as one &lt;code&gt;match&lt;/code&gt; on the string.&lt;/li&gt;
&lt;li&gt;[ ] A method &lt;code&gt;impl Op { fn apply(self, a: i64, b: i64) -&amp;gt; Option&amp;lt;i64&amp;gt; }&lt;/code&gt; that returns &lt;code&gt;None&lt;/code&gt; on overflow and on division by zero.&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;fn eval(expr: &amp;amp;str) -&amp;gt; Option&amp;lt;i64&amp;gt;&lt;/code&gt; using your &lt;code&gt;Stack&lt;/code&gt;. Use &lt;code&gt;?&lt;/code&gt; so you never write nested matches on &lt;code&gt;pop()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;main&lt;/code&gt; uses &lt;code&gt;let else&lt;/code&gt; for the missing argument and exits with code 1 on any error. No &lt;code&gt;unwrap()&lt;/code&gt;, no &lt;code&gt;.clone()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;[ ] Tests for &lt;code&gt;eval&lt;/code&gt;: the examples above, plus empty input, an unknown token like &lt;code&gt;x&lt;/code&gt;, and leftover values like &lt;code&gt;"1 2"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;cargo fmt --check &amp;amp;&amp;amp; cargo clippy -- -D warnings &amp;amp;&amp;amp; cargo test&lt;/code&gt; pass.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Hints (read only when stuck)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Most &lt;code&gt;Stack&lt;/code&gt; methods are one line that forwards to a &lt;code&gt;Vec&lt;/code&gt; method. Look at &lt;code&gt;Vec::pop&lt;/code&gt; and &lt;code&gt;slice::last&lt;/code&gt; in the docs.&lt;/li&gt;
&lt;li&gt;In &lt;code&gt;parse_token&lt;/code&gt;, a &lt;code&gt;_ =&amp;gt;&lt;/code&gt; arm can try &lt;code&gt;s.parse::&amp;lt;i64&amp;gt;()&lt;/code&gt;. That returns a &lt;code&gt;Result&lt;/code&gt;; &lt;code&gt;.ok()&lt;/code&gt; turns it into an &lt;code&gt;Option&lt;/code&gt;, and &lt;code&gt;.map(Token::Num)&lt;/code&gt; wraps the number. Yes, an enum variant can be passed as a function.&lt;/li&gt;
&lt;li&gt;Integers have &lt;code&gt;checked_add&lt;/code&gt;, &lt;code&gt;checked_sub&lt;/code&gt;, &lt;code&gt;checked_mul&lt;/code&gt; and &lt;code&gt;checked_div&lt;/code&gt;, and each returns an &lt;code&gt;Option&lt;/code&gt;. &lt;code&gt;checked_div&lt;/code&gt; already handles division by zero.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Op&lt;/code&gt; holds no data, so derive &lt;code&gt;Clone, Copy&lt;/code&gt; on it. Then &lt;code&gt;apply&lt;/code&gt; can take &lt;code&gt;self&lt;/code&gt; by value without moving anything important.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gotcha:&lt;/strong&gt; in a binary crate, a method nobody calls triggers a &lt;code&gt;dead_code&lt;/code&gt; warning, and &lt;code&gt;-D warnings&lt;/code&gt; turns that into an error. Use &lt;code&gt;len()&lt;/code&gt; and &lt;code&gt;peek()&lt;/code&gt; in &lt;code&gt;eval&lt;/code&gt; to check that exactly one value remains and to read it. That's their natural job anyway.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>programming</category>
      <category>rust</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Rust for Gophers, Lesson 2: Ownership and Borrowing</title>
      <dc:creator>Syam SV</dc:creator>
      <pubDate>Wed, 28 Oct 2026 17:17:28 +0000</pubDate>
      <link>https://dev.to/syamsv/rust-for-gophers-lesson-2-ownership-and-borrowing-82p</link>
      <guid>https://dev.to/syamsv/rust-for-gophers-lesson-2-ownership-and-borrowing-82p</guid>
      <description>&lt;h2&gt;
  
  
  1. Why ownership exists
&lt;/h2&gt;

&lt;p&gt;Ownership is how Rust frees memory without a garbage collector and without you calling &lt;code&gt;free&lt;/code&gt;. The compiler works out, at compile time, exactly where each heap value is freed. Every rule in this lesson exists to make that analysis possible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stack vs heap, quickly.&lt;/strong&gt; Values with a size known at compile time (&lt;code&gt;i32&lt;/code&gt;, &lt;code&gt;bool&lt;/code&gt;, &lt;code&gt;[u8; 4]&lt;/code&gt;, a struct of those) live on the stack and are popped when the function returns, which is free. Values that grow (&lt;code&gt;String&lt;/code&gt;, &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt;) keep a small fixed header on the stack (pointer, length, capacity) that points to a buffer on the heap. The question every language must answer is who frees that heap buffer, and when.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Who frees heap memory&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;th&gt;What can go wrong&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;You, with &lt;code&gt;free&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Use-after-free, double free, leaks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Go&lt;/td&gt;
&lt;td&gt;The garbage collector, at some point later&lt;/td&gt;
&lt;td&gt;GC CPU and pauses, more memory headroom&lt;/td&gt;
&lt;td&gt;Data races, stale aliases, leaks through long-lived references&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rust&lt;/td&gt;
&lt;td&gt;The compiler inserts the free at the end of the owner's scope&lt;/td&gt;
&lt;td&gt;None at runtime&lt;/td&gt;
&lt;td&gt;Prevented at compile time; you pay in learning effort&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Go's escape analysis already decides stack vs heap for you, and the GC handles the rest. Rust asks you to state the relationships (who owns, who borrows, for how long), and in return you get C-level performance with no use-after-free, no double free, and no data races. That last one matters for your multithreading goal: the same rules you learn today are what make concurrent Rust safe in Lesson 10.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The three rules, moves, and Drop
&lt;/h2&gt;

&lt;p&gt;Memorize these three rules; everything else follows from them.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Each value has exactly one owner (a variable, a struct field, a vector slot).&lt;/li&gt;
&lt;li&gt;Ownership can be moved to a new owner, and then the old one can no longer be used.&lt;/li&gt;
&lt;li&gt;When the owner goes out of scope, the value is dropped (its memory freed, its file closed, its lock released).&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Moves
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;s1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hi"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;s2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;          &lt;span class="c1"&gt;// ownership MOVES to s2. Only the stack header is copied&lt;/span&gt;
&lt;span class="c1"&gt;// println!("{s1}");  // error[E0382]: borrow of moved value: `s1`&lt;/span&gt;
&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{s2}"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Go, &lt;code&gt;s2 := s1&lt;/code&gt; for a slice copies the header and both variables share the same backing array. That is cheap but creates two handles to one buffer. Rust copies the header too, but then invalidates &lt;code&gt;s1&lt;/code&gt;, so there is still exactly one owner and exactly one free. No double free is possible.&lt;/p&gt;

&lt;p&gt;Passing to a function is also a move:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;takes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// s is dropped here; the heap buffer is freed&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Syam"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;takes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// takes(name);  // error: use of moved value&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Copy vs Clone
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;               &lt;span class="c1"&gt;// i32 is Copy: a bitwise copy, `a` is still valid&lt;/span&gt;
&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{a} {b}"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hi"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;       &lt;span class="c1"&gt;// explicit deep copy: allocates a new heap buffer&lt;/span&gt;
&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{s} {t}"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Copy&lt;/code&gt;&lt;/strong&gt; types are plain data with no heap ownership: integers, floats, &lt;code&gt;bool&lt;/code&gt;, &lt;code&gt;char&lt;/code&gt;, and tuples and arrays of those. Assignment copies them implicitly, so they never "move".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Clone&lt;/code&gt;&lt;/strong&gt; is an explicit, possibly expensive duplicate. Rust never deep-copies behind your back, so every allocation is visible in the code as &lt;code&gt;.clone()&lt;/code&gt;, &lt;code&gt;.to_string()&lt;/code&gt; or &lt;code&gt;.to_vec()&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A beginner habit to avoid: sprinkling &lt;code&gt;.clone()&lt;/code&gt; to silence the borrow checker. It compiles, but it hides a design problem and allocates. In reviews I'll flag every clone that a borrow could replace.&lt;/p&gt;

&lt;h3&gt;
  
  
  Drop: &lt;code&gt;defer&lt;/code&gt; that you can't forget
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;File&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"data.txt"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// use f...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// f is dropped here: the file is closed automatically&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Go you write &lt;code&gt;defer f.Close()&lt;/code&gt; and hope nobody forgets. In Rust the cleanup is tied to the owner's scope (this pattern is called RAII), so files, sockets, mutex locks and DB connections are always released, even on early return or panic. You'll see this pay off with &lt;code&gt;MutexGuard&lt;/code&gt; in Lesson 10 and connection pools in Lesson 15.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Borrowing: references without ownership
&lt;/h2&gt;

&lt;p&gt;Moving everything everywhere would be unbearable, so Rust lets you &lt;strong&gt;borrow&lt;/strong&gt;: hand out a reference that uses the value without owning it. The owner keeps responsibility for dropping it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;len_of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;   &lt;span class="c1"&gt;// shared borrow: read-only&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;excite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;     &lt;span class="c1"&gt;// mutable borrow: can modify&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'!'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;excite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;                 &lt;span class="c1"&gt;// the call site says &amp;amp;mut, so mutation is visible&lt;/span&gt;
&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{} {g}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;len_of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// 6 hello!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A reference is a pointer that the compiler has proven is valid. Unlike a Go pointer, it can never be nil and can never outlive the thing it points to.&lt;/p&gt;

&lt;h3&gt;
  
  
  The one rule of borrowing
&lt;/h3&gt;

&lt;p&gt;At any moment, a value can have &lt;strong&gt;either&lt;/strong&gt; any number of shared references &lt;code&gt;&amp;amp;T&lt;/code&gt;, &lt;strong&gt;or&lt;/strong&gt; exactly one mutable reference &lt;code&gt;&amp;amp;mut T&lt;/code&gt;. Never both.&lt;/p&gt;

&lt;p&gt;This is the readers-writer lock pattern, enforced at compile time with zero runtime cost. Think of &lt;code&gt;&amp;amp;T&lt;/code&gt; as "shared, read-only" and &lt;code&gt;&amp;amp;mut T&lt;/code&gt; as "exclusive". The precise names matter more than the keywords: &lt;code&gt;&amp;amp;mut&lt;/code&gt; really means &lt;em&gt;unique&lt;/em&gt; access.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Go bug this prevents
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// Go: compiles, runs, and is silently wrong&lt;/span&gt;
&lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c"&gt;// may reallocate to a new backing array&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;       &lt;span class="c"&gt;// writes to the OLD array; v[0] is still 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Rust: refuses to compile&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;       &lt;span class="c1"&gt;// shared borrow of v starts&lt;/span&gt;
&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;               &lt;span class="c1"&gt;// error[E0502]: cannot borrow `v` as mutable&lt;/span&gt;
                         &lt;span class="c1"&gt;// because it is also borrowed as immutable&lt;/span&gt;
&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{first}"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;     &lt;span class="c1"&gt;// shared borrow is still alive here&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Go the GC keeps the old array alive, so it isn't a crash, just a quiet logic bug. In C++ the same code is a use-after-free. In Rust it can't be written. The exact same rule, applied across threads, is why Rust has no data races: two threads can't both hold &lt;code&gt;&amp;amp;mut&lt;/code&gt; to the same data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Borrows end at their last use
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{first}"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// last use of `first`: the borrow ends here&lt;/span&gt;
&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;             &lt;span class="c1"&gt;// fine&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The compiler tracks where each reference is last used, not where its variable goes out of scope (this is called non-lexical lifetimes). Reordering code like this is often the whole fix for a borrow error.&lt;/p&gt;

&lt;h3&gt;
  
  
  No dangling references
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;make&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;        &lt;span class="c1"&gt;// error[E0106]: missing lifetime specifier&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hi"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;                        &lt;span class="c1"&gt;// s is dropped at the end of make()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Go, returning &lt;code&gt;&amp;amp;s&lt;/code&gt; is fine because escape analysis moves &lt;code&gt;s&lt;/code&gt; to the heap. Rust won't silently heap-allocate. The fix is to return the owned value, &lt;code&gt;fn make() -&amp;gt; String&lt;/code&gt;, which moves ownership out to the caller at no cost. "Missing lifetime specifier" is the compiler asking how long the reference should live; we cover lifetimes properly in Lesson 8.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Slices, and &lt;code&gt;String&lt;/code&gt; vs &lt;code&gt;&amp;amp;str&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;A slice is a borrowed view into a contiguous sequence: a pointer plus a length, with no capacity. It is Go's slice header minus &lt;code&gt;cap&lt;/code&gt;, and it never owns its data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;xs&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.sum&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;        &lt;span class="c1"&gt;// &amp;amp;Vec&amp;lt;i32&amp;gt; coerces to &amp;amp;[i32] automatically&lt;/span&gt;
&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;   &lt;span class="c1"&gt;// a sub-slice: [2, 3, 4]&lt;/span&gt;
&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;   &lt;span class="c1"&gt;// an array works too&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You cannot &lt;code&gt;append&lt;/code&gt; to a slice in Rust. Growth needs ownership, so only the &lt;code&gt;Vec&lt;/code&gt; can grow. That removes Go's entire class of "did my append alias the caller's array" bugs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Two string types
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;String&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;&amp;amp;str&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;What it is&lt;/td&gt;
&lt;td&gt;Owned, growable UTF-8 buffer on the heap&lt;/td&gt;
&lt;td&gt;Borrowed view into UTF-8 bytes somewhere&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Analogy&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Vec&amp;lt;u8&amp;gt;&lt;/code&gt; that is guaranteed valid UTF-8&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;&amp;amp;[u8]&lt;/code&gt; that is guaranteed valid UTF-8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Go analogy&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;strings.Builder&lt;/code&gt; / &lt;code&gt;[]byte&lt;/code&gt; you own&lt;/td&gt;
&lt;td&gt;Go's &lt;code&gt;string&lt;/code&gt; (an immutable view)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Literals&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;String::from("hi")&lt;/code&gt;, &lt;code&gt;"hi".to_string()&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;"hi"&lt;/code&gt; is a &lt;code&gt;&amp;amp;'static str&lt;/code&gt; baked into the binary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use for&lt;/td&gt;
&lt;td&gt;Struct fields, return values, anything you build&lt;/td&gt;
&lt;td&gt;Function parameters that only read&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;first_word&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="nf"&gt;.find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;   &lt;span class="c1"&gt;// a slice of the input; no allocation&lt;/span&gt;
        &lt;span class="nb"&gt;None&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello world"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;first_word&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;             &lt;span class="c1"&gt;// &amp;amp;String coerces to &amp;amp;str&lt;/span&gt;
&lt;span class="nf"&gt;first_word&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"literal works"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// so does a literal&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The returned &lt;code&gt;&amp;amp;str&lt;/code&gt; borrows from the input, so the compiler won't let &lt;code&gt;line&lt;/code&gt; be modified or dropped while the result is in use. In Go, &lt;code&gt;bytes.Fields&lt;/code&gt; gives you zero-copy sub-slices too, but nothing stops you from mutating the underlying &lt;code&gt;[]byte&lt;/code&gt; while they are in use.&lt;/p&gt;

&lt;h3&gt;
  
  
  UTF-8: bytes are not characters
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"héllo"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;               &lt;span class="c1"&gt;// 6, bytes (é is 2 bytes), like len() in Go&lt;/span&gt;
&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="nf"&gt;.chars&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.count&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;     &lt;span class="c1"&gt;// 5, Unicode scalar values, like utf8.RuneCountInString&lt;/span&gt;
&lt;span class="c1"&gt;// s[0]                // error: strings can't be indexed by integer&lt;/span&gt;
&lt;span class="c1"&gt;// &amp;amp;s[0..2]            // compiles, but PANICS: byte 2 is inside 'é'&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="nf"&gt;.char_indices&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* like `for i, r := range s` in Go */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rust forbids &lt;code&gt;s[0]&lt;/code&gt; because it would be ambiguous (byte or character?) and O(1)-looking while really needing a scan. Slicing by byte range is allowed but panics if you cut through a character. In real code, find boundaries with &lt;code&gt;find&lt;/code&gt;, &lt;code&gt;split_whitespace&lt;/code&gt;, &lt;code&gt;char_indices&lt;/code&gt;, or work on &lt;code&gt;s.as_bytes()&lt;/code&gt; when you truly have ASCII, as you will in the base64 lesson.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Choosing function signatures
&lt;/h2&gt;

&lt;p&gt;Every parameter answers one question: does this function need to own the value, change it, or just look at it? Pick the weakest access that works.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Signature&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;th&gt;Caller writes&lt;/th&gt;
&lt;th&gt;Use when&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;fn f(x: &amp;amp;T)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Read-only borrow&lt;/td&gt;
&lt;td&gt;&lt;code&gt;f(&amp;amp;x)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Default for reading. Most parameters&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;fn f(x: &amp;amp;mut T)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Exclusive borrow, may modify&lt;/td&gt;
&lt;td&gt;&lt;code&gt;f(&amp;amp;mut x)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Changing the caller's value in place&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;fn f(x: T)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Takes ownership&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;f(x)&lt;/code&gt; (moved)&lt;/td&gt;
&lt;td&gt;Storing it, sending it to another thread, or consuming it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;fn f() -&amp;gt; T&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Gives ownership to the caller&lt;/td&gt;
&lt;td&gt;&lt;code&gt;let x = f();&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Creating new values. Returning owned values is cheap: a move, not a copy&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Industry conventions clippy will push you towards:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Take &lt;code&gt;&amp;amp;str&lt;/code&gt;, not &lt;code&gt;&amp;amp;String&lt;/code&gt;, and &lt;code&gt;&amp;amp;[T]&lt;/code&gt;, not &lt;code&gt;&amp;amp;Vec&amp;lt;T&amp;gt;&lt;/code&gt;. The slice form accepts more callers (literals, arrays, sub-slices) and gives up nothing. Clippy's &lt;code&gt;ptr_arg&lt;/code&gt; lint flags the other form.&lt;/li&gt;
&lt;li&gt;Return owned types (&lt;code&gt;String&lt;/code&gt;, &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt;) from functions that build new data. Return &lt;code&gt;&amp;amp;str&lt;/code&gt;/&lt;code&gt;&amp;amp;[T]&lt;/code&gt; only when you are handing back a piece of an input.&lt;/li&gt;
&lt;li&gt;Go's habit of passing a pointer "to avoid copying" doesn't carry over. Moves never deep-copy, so &lt;code&gt;fn f(x: BigStruct)&lt;/code&gt; is fine when you want ownership.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mut&lt;/code&gt; in a signature is visible at every call site (&lt;code&gt;&amp;amp;mut x&lt;/code&gt;). When you read Rust code, you always know which calls can change your data. Go gives you no such signal for pointers or slices.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  6. Compiler error drills
&lt;/h2&gt;

&lt;p&gt;Before you write the exercise, work through these five snippets. Each one is broken. For each one, &lt;strong&gt;predict the problem before you compile it&lt;/strong&gt;, then paste it into &lt;code&gt;src/main.rs&lt;/code&gt;, read the full error (&lt;code&gt;cargo check&lt;/code&gt;), and fix it in the most idiomatic way, without using &lt;code&gt;.clone()&lt;/code&gt;. Learning to read borrow-checker errors is the real skill here; they are some of the best error messages in any language.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Drill 1&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"b"&lt;/span&gt;&lt;span class="p"&gt;)];&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{x}"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Drill 2&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;r1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;r2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;r2&lt;/span&gt;&lt;span class="nf"&gt;.push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'b'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{r1}"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Drill 3&lt;/strong&gt; (fix it two different ways)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;make&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hi"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Drill 4&lt;/strong&gt; (this one compiles; what happens when it runs?)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"héllo"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;part&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{part}"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Drill 5&lt;/strong&gt; (stretch: a preview of Lesson 8)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;i
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The compiler's suggestion will add &lt;code&gt;&amp;lt;'a&amp;gt;&lt;/code&gt;. Apply it, then explain in one sentence why the compiler couldn't figure this out alone when it could for &lt;code&gt;first_word&lt;/code&gt; in section 4.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Exercise: &lt;code&gt;wordy&lt;/code&gt;, a word counter
&lt;/h2&gt;

&lt;p&gt;Build a small &lt;code&gt;wc&lt;/code&gt;-style tool. The point is to practice choosing between &lt;code&gt;&amp;amp;str&lt;/code&gt;, &lt;code&gt;String&lt;/code&gt; and &lt;code&gt;&amp;amp;mut String&lt;/code&gt;, and returning borrowed slices from your inputs. Finish fizzbuzz v2 first if you haven't yet.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo new wordy &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;wordy
&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'The quick brown fox\njumps over the lazy dog\n'&lt;/span&gt; | cargo run
&lt;span class="c"&gt;#        2       9      43      43&lt;/span&gt;
&lt;span class="c"&gt;# longest: quick&lt;/span&gt;
&lt;span class="c"&gt;# long words: ["quick", "brown", "jumps"]&lt;/span&gt;
cargo run &lt;span class="nt"&gt;--&lt;/span&gt; notes.txt     &lt;span class="c"&gt;# reads a file instead of stdin&lt;/span&gt;
cargo run &lt;span class="nt"&gt;--&lt;/span&gt; missing.txt   &lt;span class="c"&gt;# stderr: error: No such file or directory (os error 2), exit 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Requirements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] &lt;code&gt;fn count(text: &amp;amp;str) -&amp;gt; (usize, usize, usize, usize)&lt;/code&gt;: lines, words, chars, bytes. Print them right-aligned in 8-wide columns like &lt;code&gt;wc&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;fn longest_word(text: &amp;amp;str) -&amp;gt; Option&amp;lt;&amp;amp;str&amp;gt;&lt;/code&gt;: the longest word measured in characters (not bytes), first one wins a tie, &lt;code&gt;None&lt;/code&gt; for empty input. It must return a slice of &lt;code&gt;text&lt;/code&gt;, with no allocation.&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;fn words_longer_than(text: &amp;amp;str, n: usize) -&amp;gt; Vec&amp;lt;&amp;amp;str&amp;gt;&lt;/code&gt;: all words with more than &lt;code&gt;n&lt;/code&gt; characters, as slices of &lt;code&gt;text&lt;/code&gt;. Print them for &lt;code&gt;n = 4&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;fn normalize(text: &amp;amp;mut String)&lt;/code&gt;: lowercases ASCII letters and strips trailing whitespace &lt;strong&gt;in place&lt;/strong&gt;, without creating a new &lt;code&gt;String&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;main&lt;/code&gt; reads the file named by the first argument, or stdin if there is none. Any I/O error goes to stderr with exit code 1. No &lt;code&gt;unwrap()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;[ ] Tests: at least one per function, including empty input, a tie in &lt;code&gt;longest_word&lt;/code&gt;, and a non-ASCII word such as &lt;code&gt;héllo&lt;/code&gt; where chars and bytes differ.&lt;/li&gt;
&lt;li&gt;[ ] Zero &lt;code&gt;.clone()&lt;/code&gt; calls, and &lt;code&gt;cargo fmt --check &amp;amp;&amp;amp; cargo clippy -- -D warnings &amp;amp;&amp;amp; cargo test&lt;/code&gt; pass.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Hints (read only when stuck)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;str&lt;/code&gt; already has what you need: &lt;code&gt;lines()&lt;/code&gt;, &lt;code&gt;split_whitespace()&lt;/code&gt;, &lt;code&gt;chars()&lt;/code&gt;, &lt;code&gt;len()&lt;/code&gt;. Look them up in &lt;code&gt;cargo doc --open&lt;/code&gt; under &lt;code&gt;str&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Reading input: &lt;code&gt;std::fs::read_to_string(path)&lt;/code&gt; and &lt;code&gt;std::io::read_to_string(std::io::stdin())&lt;/code&gt; both return &lt;code&gt;Result&amp;lt;String, io::Error&amp;gt;&lt;/code&gt;. Match on &lt;code&gt;env::args().nth(1)&lt;/code&gt; to choose which one to call, then match the result once.&lt;/li&gt;
&lt;li&gt;For &lt;code&gt;longest_word&lt;/code&gt;, keep an &lt;code&gt;Option&amp;lt;&amp;amp;str&amp;gt;&lt;/code&gt; for the best so far. A &lt;code&gt;match&lt;/code&gt; arm can have a guard: &lt;code&gt;Some(b) if condition =&amp;gt; ...&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;For &lt;code&gt;normalize&lt;/code&gt;, look for a &lt;code&gt;make_ascii_*&lt;/code&gt; method on &lt;code&gt;String&lt;/code&gt;, and for a method that shortens a &lt;code&gt;String&lt;/code&gt; to a given length. &lt;code&gt;trim_end()&lt;/code&gt; tells you what that length should be.&lt;/li&gt;
&lt;li&gt;When the compiler says something "does not live long enough" or "cannot borrow as mutable", draw on paper who owns each value and when each borrow is last used.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>programming</category>
      <category>rust</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Rust for Gophers, Lesson 1: Hello, Cargo</title>
      <dc:creator>Syam SV</dc:creator>
      <pubDate>Wed, 28 Oct 2026 17:14:17 +0000</pubDate>
      <link>https://dev.to/syamsv/rust-for-gophers-lesson-1-hello-cargo-40h0</link>
      <guid>https://dev.to/syamsv/rust-for-gophers-lesson-1-hello-cargo-40h0</guid>
      <description>&lt;h2&gt;
  
  
  The roadmap
&lt;/h2&gt;

&lt;p&gt;We go from hello world to an async web service with a database in 16 lessons, and every lesson ends with a program you write by hand. Each phase builds the muscle the next one needs: you cannot write a sane async server until ownership and traits feel natural, so we don't rush there.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Lesson&lt;/th&gt;
&lt;th&gt;What you build&lt;/th&gt;
&lt;th&gt;Go concept it replaces&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Toolchain, basics, tests (today)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;greet&lt;/code&gt; + &lt;code&gt;fizzbuzz&lt;/code&gt; with tests&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;go mod&lt;/code&gt;, &lt;code&gt;go test&lt;/code&gt;, &lt;code&gt;gofmt&lt;/code&gt;, &lt;code&gt;go vet&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Ownership, borrowing, slices, &lt;code&gt;String&lt;/code&gt; vs &lt;code&gt;&amp;amp;str&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Word counter&lt;/td&gt;
&lt;td&gt;GC + pointers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Structs, enums, &lt;code&gt;match&lt;/code&gt;, &lt;code&gt;Option&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Stack data structure&lt;/td&gt;
&lt;td&gt;structs, &lt;code&gt;nil&lt;/code&gt;, iota&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Error handling: &lt;code&gt;Result&lt;/code&gt;, &lt;code&gt;?&lt;/code&gt;, custom errors&lt;/td&gt;
&lt;td&gt;Base64 encoder/decoder&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;if err != nil&lt;/code&gt;, &lt;code&gt;errors.Is&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Traits and generics&lt;/td&gt;
&lt;td&gt;Generic stack + &lt;code&gt;Display&lt;/code&gt;/&lt;code&gt;Iterator&lt;/code&gt; impls&lt;/td&gt;
&lt;td&gt;interfaces, generics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Collections and iterators&lt;/td&gt;
&lt;td&gt;Log file analyzer&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;for range&lt;/code&gt;, maps, slices&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Modules, crates, workspaces&lt;/td&gt;
&lt;td&gt;Split the base64 tool into lib + bin&lt;/td&gt;
&lt;td&gt;packages, &lt;code&gt;internal/&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Lifetimes in depth&lt;/td&gt;
&lt;td&gt;Zero-copy tokenizer&lt;/td&gt;
&lt;td&gt;escape analysis&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;Real CLIs: &lt;code&gt;clap&lt;/code&gt;, &lt;code&gt;anyhow&lt;/code&gt;, &lt;code&gt;thiserror&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;grep&lt;/code&gt;-like CLI tool&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;flag&lt;/code&gt;, &lt;code&gt;cobra&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;Threads: &lt;code&gt;std::thread&lt;/code&gt;, &lt;code&gt;Arc&lt;/code&gt;, &lt;code&gt;Mutex&lt;/code&gt;, channels&lt;/td&gt;
&lt;td&gt;Parallel file hasher&lt;/td&gt;
&lt;td&gt;goroutines, &lt;code&gt;sync&lt;/code&gt;, chans&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Send&lt;/code&gt;/&lt;code&gt;Sync&lt;/code&gt; and fearless concurrency&lt;/td&gt;
&lt;td&gt;Thread pool from scratch&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;sync.WaitGroup&lt;/code&gt;, worker pools&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;Raw HTTP over &lt;code&gt;TcpListener&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Tiny HTTP/1.1 server by hand&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;net&lt;/code&gt; package&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;Async Rust: futures, &lt;code&gt;tokio&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Async chat server&lt;/td&gt;
&lt;td&gt;goroutines + &lt;code&gt;select&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;Web with &lt;code&gt;axum&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;JSON REST API&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;net/http&lt;/code&gt;, chi/gin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;Databases with &lt;code&gt;sqlx&lt;/code&gt; + Postgres&lt;/td&gt;
&lt;td&gt;CRUD service&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;database/sql&lt;/code&gt;, pgx&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;Production polish: tracing, config, testing, CI&lt;/td&gt;
&lt;td&gt;Ship the CRUD service&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;slog&lt;/code&gt;, &lt;code&gt;testing&lt;/code&gt;, CI&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;How each lesson works: I explain the concepts, you write the exercise yourself and paste your code here, then I review it like a senior engineer would on a PR. I give hints before answers, and a full solution only if you ask for one.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Setup and tooling
&lt;/h2&gt;

&lt;p&gt;Install Rust with &lt;code&gt;rustup&lt;/code&gt;, the official toolchain manager. It is like having &lt;code&gt;go&lt;/code&gt; plus a version manager in one tool.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--proto&lt;/span&gt; &lt;span class="s1"&gt;'=https'&lt;/span&gt; &lt;span class="nt"&gt;--tlsv1&lt;/span&gt;.2 &lt;span class="nt"&gt;-sSf&lt;/span&gt; https://sh.rustup.rs | sh
rustup component add rustfmt clippy   &lt;span class="c"&gt;# usually installed by default&lt;/span&gt;
rustc &lt;span class="nt"&gt;--version&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; cargo &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The pieces you get:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;th&gt;Go equivalent&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rustup&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Installs and switches toolchains (stable, beta, nightly)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;go install golang.org/dl/...&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rustc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The compiler. You almost never call it directly&lt;/td&gt;
&lt;td&gt;&lt;code&gt;go tool compile&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cargo&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Build, run, test, deps, docs, publish&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;go&lt;/code&gt; command&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;rustfmt&lt;/code&gt; (&lt;code&gt;cargo fmt&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;The one true formatter&lt;/td&gt;
&lt;td&gt;&lt;code&gt;gofmt&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;clippy&lt;/code&gt; (&lt;code&gt;cargo clippy&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;700+ lints for bugs and non-idiomatic code&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;go vet&lt;/code&gt; + &lt;code&gt;staticcheck&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rust-analyzer&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Language server for your editor&lt;/td&gt;
&lt;td&gt;&lt;code&gt;gopls&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Install the rust-analyzer extension in your editor now. It shows inferred types inline, which is the single biggest help while learning.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a project
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo new hello_rust      &lt;span class="c"&gt;# binary crate (has main.rs)&lt;/span&gt;
cargo new mylib &lt;span class="nt"&gt;--lib&lt;/span&gt;     &lt;span class="c"&gt;# library crate (has lib.rs)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hello_rust/
├── Cargo.toml     # manifest: name, version, edition, dependencies (like go.mod)
├── Cargo.lock     # exact resolved versions (like go.sum); commit it for binaries
├── src/
│   └── main.rs    # crate root for a binary
└── target/        # build output; git-ignored
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="k"&gt;[&lt;/span&gt;&lt;span class="n"&gt;package&lt;/span&gt;&lt;span class="k"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"hello_rust"&lt;/span&gt;
&lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"0.1.0"&lt;/span&gt;
&lt;span class="n"&gt;edition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"2024"&lt;/span&gt;

&lt;span class="k"&gt;[&lt;/span&gt;&lt;span class="n"&gt;dependencies&lt;/span&gt;&lt;span class="k"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;edition&lt;/code&gt; is a Rust-specific idea. Editions (2015, 2018, 2021, 2024) let the language make small breaking syntax changes without breaking old code, and crates of different editions link together fine. Always use the latest for new code.&lt;/p&gt;

&lt;h3&gt;
  
  
  The commands you will type every day
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cargo check&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Type-checks without producing a binary. Fastest feedback; run it constantly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;cargo build&lt;/code&gt; / &lt;code&gt;cargo build --release&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Debug build (fast compile, slow code) / optimized build&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cargo run -- arg1 arg2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Build and run; everything after &lt;code&gt;--&lt;/code&gt; goes to your program&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cargo test&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Runs unit, integration and doc tests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cargo fmt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Formats all code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cargo clippy -- -D warnings&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Lints, and treats warnings as errors (what CI should do)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cargo doc --open&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Builds HTML docs for your crate and all its dependencies&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cargo add serde&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Adds a dependency to Cargo.toml&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Industry habit: before every commit run &lt;code&gt;cargo fmt &amp;amp;&amp;amp; cargo clippy -- -D warnings &amp;amp;&amp;amp; cargo test&lt;/code&gt;. Clippy is a teacher, not a nag; read every lint it gives you, because each one links to an explanation.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Hello world, dissected
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, world!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three lines, and four ideas worth understanding properly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;fn main()&lt;/code&gt; is the entry point.&lt;/strong&gt; Like Go's &lt;code&gt;func main()&lt;/code&gt; but with no &lt;code&gt;package main&lt;/code&gt; line: the crate root file (&lt;code&gt;src/main.rs&lt;/code&gt;) plays that role. &lt;code&gt;main&lt;/code&gt; can also return &lt;code&gt;Result&amp;lt;(), E&amp;gt;&lt;/code&gt;, which we will use from Lesson 4 so errors exit with a non-zero code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;println!&lt;/code&gt; is a macro, not a function.&lt;/strong&gt; The &lt;code&gt;!&lt;/code&gt; marks a macro call. Macros run at compile time and generate code. That is why &lt;code&gt;println!&lt;/code&gt; can take a variable number of arguments and check your format string at compile time: &lt;code&gt;println!("{} {}", a)&lt;/code&gt; is a compile error, while Go's &lt;code&gt;fmt.Printf&lt;/code&gt; only catches that in &lt;code&gt;go vet&lt;/code&gt;. Formatting basics:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Syam"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;pi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;3.14159&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hi {name}"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;          &lt;span class="c1"&gt;// inline variable capture&lt;/span&gt;
&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hi {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;        &lt;span class="c1"&gt;// positional&lt;/span&gt;
&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{pi:.2}"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;            &lt;span class="c1"&gt;// 3.14, like %.2f&lt;/span&gt;
&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{:?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;    &lt;span class="c1"&gt;// Debug output, like %v&lt;/span&gt;
&lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{:#?}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;some_struct&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// pretty Debug, like %+v on multiple lines&lt;/span&gt;
&lt;span class="nd"&gt;eprintln!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"to stderr"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;         &lt;span class="c1"&gt;// like fmt.Fprintln(os.Stderr, ...)&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{name}!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;     &lt;span class="c1"&gt;// like fmt.Sprintf&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;{}&lt;/code&gt; uses the &lt;code&gt;Display&lt;/code&gt; trait (human-facing output) and &lt;code&gt;{:?}&lt;/code&gt; uses &lt;code&gt;Debug&lt;/code&gt; (developer-facing). A type must opt in to each one; we cover traits in Lesson 5.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Semicolons matter.&lt;/strong&gt; They turn an expression into a statement. This sounds trivial, but it is the key to the next section.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The compile model.&lt;/strong&gt; &lt;code&gt;cargo build&lt;/code&gt; compiles your whole crate as one unit and produces a single native binary with no runtime and no garbage collector, so there is no GC pause and the binary starts instantly. The price is slower compiles than Go. That is why &lt;code&gt;cargo check&lt;/code&gt; exists: it skips code generation and is usually several times faster.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Core basics, the Go programmer's way
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Variables are immutable by default
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;         &lt;span class="c1"&gt;// immutable binding, type inferred as i32&lt;/span&gt;
&lt;span class="c1"&gt;// x = 6;          // compile error: cannot assign twice to immutable variable&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;     &lt;span class="c1"&gt;// opt in to mutation&lt;/span&gt;
&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;MAX_USERS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1_000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// compile-time constant, type always required&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Go everything is mutable and you trust yourself. In Rust, &lt;code&gt;mut&lt;/code&gt; is a signal to the reader: "this value changes, watch it." Industry style is to make things mutable only when you need to; clippy and the compiler warn about unneeded &lt;code&gt;mut&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Shadowing
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;spaces&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"   "&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;          &lt;span class="c1"&gt;// &amp;amp;str&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;spaces&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;spaces&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;   &lt;span class="c1"&gt;// new variable, now usize; the old one is hidden&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is not mutation; it creates a new binding, and the type can change. It is idiomatic for transforming a value step by step (parse input, then validate it) without inventing names like &lt;code&gt;spacesStr&lt;/code&gt; and &lt;code&gt;spacesLen&lt;/code&gt;. Go forbids this in the same scope.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scalar types
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rust&lt;/th&gt;
&lt;th&gt;Go&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;i8 i16 i32 i64 i128&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;int8 … int64&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;i32&lt;/code&gt; is the default integer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;u8 u16 u32 u64 u128&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;uint8 … uint64&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;u8&lt;/code&gt; is a byte&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;isize&lt;/code&gt; / &lt;code&gt;usize&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;int&lt;/code&gt; / &lt;code&gt;uint&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Pointer-sized. Indexes and lengths are always &lt;code&gt;usize&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;f32&lt;/code&gt; / &lt;code&gt;f64&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;float32&lt;/code&gt; / &lt;code&gt;float64&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;f64&lt;/code&gt; is the default&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;char&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rune&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;4 bytes, one Unicode scalar value&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Two differences that bite Go programmers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No implicit conversions, ever.&lt;/strong&gt; Not even &lt;code&gt;i32&lt;/code&gt; to &lt;code&gt;i64&lt;/code&gt;. You write &lt;code&gt;x as i64&lt;/code&gt; for a lossy/primitive cast, or &lt;code&gt;i64::from(x)&lt;/code&gt; for a lossless one. Prefer &lt;code&gt;from&lt;/code&gt;/&lt;code&gt;try_from&lt;/code&gt; in real code because &lt;code&gt;as&lt;/code&gt; silently truncates (&lt;code&gt;300_i32 as u8&lt;/code&gt; is 44).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integer overflow is a bug, not a feature.&lt;/strong&gt; In debug builds &lt;code&gt;u8::MAX + 1&lt;/code&gt; panics; in release it wraps. When you want a specific behaviour say so: &lt;code&gt;checked_add&lt;/code&gt; (returns &lt;code&gt;Option&lt;/code&gt;), &lt;code&gt;wrapping_add&lt;/code&gt;, &lt;code&gt;saturating_add&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Compound types
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;f64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"two"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// tuple, fixed size, mixed types&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                         &lt;span class="c1"&gt;// destructuring&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="na"&gt;.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;             &lt;span class="c1"&gt;// fixed-size array, like Go's [3]int&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;zeros&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0u8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;                   &lt;span class="c1"&gt;// 1024 zero bytes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The growable list (Go's slice) is &lt;code&gt;Vec&amp;lt;T&amp;gt;&lt;/code&gt;, and the empty tuple &lt;code&gt;()&lt;/code&gt; ("unit") is what functions return when they return nothing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Functions, and the big idea: everything is an expression
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;      &lt;span class="c1"&gt;// no semicolon: this is the return value&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Parameter and return types are always written; Rust never infers function signatures, so a signature is a contract you can read. The last expression in a block, written without a semicolon, is the block's value. Add a &lt;code&gt;;&lt;/code&gt; and it becomes a statement that evaluates to &lt;code&gt;()&lt;/code&gt;, giving you the classic beginner error &lt;code&gt;expected i32, found ()&lt;/code&gt;. Use &lt;code&gt;return&lt;/code&gt; only for early exits.&lt;/p&gt;

&lt;p&gt;Because blocks are expressions, &lt;code&gt;if&lt;/code&gt; and &lt;code&gt;match&lt;/code&gt; produce values. Rust has no ternary operator because it doesn't need one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"world"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Control flow
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// loop: infinite loop that can return a value via break&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// while&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// for over a range: 1..5 is 1 to 4, 1..=5 includes 5&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{i}"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// for over a collection, like `for _, v := range items`&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* borrow each */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.enumerate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* like `for i, v := range` */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is no C-style &lt;code&gt;for i := 0; i &amp;lt; n; i++&lt;/code&gt;. Ranges and iterators replace it, and they remove off-by-one and out-of-bounds bugs.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;match&lt;/code&gt;: switch with superpowers
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;'static&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"ok"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="mi"&gt;301&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;302&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"redirect"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="o"&gt;..=&lt;/span&gt;&lt;span class="mi"&gt;499&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"client error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="o"&gt;..=&lt;/span&gt;&lt;span class="mi"&gt;599&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"server error"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"unknown"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;match&lt;/code&gt; must be exhaustive: the compiler refuses to build if a case is missing, which is why &lt;code&gt;_&lt;/code&gt; (the catch-all) exists. Unlike Go's &lt;code&gt;switch&lt;/code&gt;, there is no fallthrough and arms are expressions. This becomes enormously powerful with enums in Lesson 3.&lt;/p&gt;

&lt;p&gt;Ignore the &lt;code&gt;&amp;amp;'static str&lt;/code&gt; for now. It means "a reference to a string that lives for the whole program", which is what string literals are. Lesson 2 is entirely about what &lt;code&gt;&amp;amp;&lt;/code&gt; means.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Testing from day one
&lt;/h2&gt;

&lt;p&gt;Rust's convention is to put unit tests in the same file as the code, inside a &lt;code&gt;tests&lt;/code&gt; module that only compiles under &lt;code&gt;cargo test&lt;/code&gt;. Go puts them in a separate &lt;code&gt;_test.go&lt;/code&gt; file; Rust keeps them next to the code they check.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;greeting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, {name}!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;#[cfg(test)]&lt;/span&gt;          &lt;span class="c1"&gt;// compile this module only when testing&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;tests&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;     &lt;span class="c1"&gt;// bring the parent module's items into scope&lt;/span&gt;

    &lt;span class="nd"&gt;#[test]&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;greets_by_name&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;greeting&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Syam"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;"Hello, Syam!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;#[test]&lt;/span&gt;
    &lt;span class="nd"&gt;#[should_panic]&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;overflow_panics_in_debug&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u8&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;hint&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;black_box&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;assert_eq!(left, right)&lt;/code&gt; and &lt;code&gt;assert_ne!&lt;/code&gt; print both values on failure; &lt;code&gt;assert!(cond, "message {x}")&lt;/code&gt; for anything else. There is no &lt;code&gt;t.Errorf&lt;/code&gt;: a failing assertion panics, and the test runner catches it.&lt;/li&gt;
&lt;li&gt;Tests run in parallel threads by default, like &lt;code&gt;t.Parallel()&lt;/code&gt; everywhere.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cargo test greets&lt;/code&gt; runs only tests whose name contains &lt;code&gt;greets&lt;/code&gt;, like &lt;code&gt;go test -run&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cargo test -- --nocapture&lt;/code&gt; shows &lt;code&gt;println!&lt;/code&gt; output, which is hidden for passing tests.&lt;/li&gt;
&lt;li&gt;Unit tests can call private functions, because the &lt;code&gt;tests&lt;/code&gt; module is a child of the module under test. Integration tests (Lesson 7) live in a top-level &lt;code&gt;tests/&lt;/code&gt; directory and only see your public API, like Go's &lt;code&gt;package foo_test&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. Your exercise: &lt;code&gt;fizzbuzz&lt;/code&gt; CLI
&lt;/h2&gt;

&lt;p&gt;Build a small CLI that takes a number and prints FizzBuzz up to it, with tests, and passes fmt and clippy cleanly. Write it yourself, no AI autocompletion, and keep the compiler's error messages open: reading them is half the skill.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo new fizz
&lt;span class="nb"&gt;cd &lt;/span&gt;fizz
cargo run &lt;span class="nt"&gt;--&lt;/span&gt; 15     &lt;span class="c"&gt;# prints 1, 2, Fizz, 4, Buzz, ... FizzBuzz&lt;/span&gt;
cargo run           &lt;span class="c"&gt;# prints to stderr: usage: fizz &amp;lt;N&amp;gt;   and exits with code 1&lt;/span&gt;
cargo run &lt;span class="nt"&gt;--&lt;/span&gt; abc    &lt;span class="c"&gt;# prints to stderr: error: 'abc' is not a valid number   exit code 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Requirements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] &lt;code&gt;fn fizzbuzz(n: u32) -&amp;gt; String&lt;/code&gt;: "Fizz" for multiples of 3, "Buzz" for 5, "FizzBuzz" for both, otherwise the number. Implement it with a single &lt;code&gt;match&lt;/code&gt;, not an if/else chain.&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;fn sum_of_multiples(limit: u32) -&amp;gt; u64&lt;/code&gt;: the sum of all numbers below &lt;code&gt;limit&lt;/code&gt; divisible by 3 or 5 (for 10 it is 23). Note the return type is wider than the input; convert without &lt;code&gt;as&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;main&lt;/code&gt; reads the first argument with &lt;code&gt;std::env::args()&lt;/code&gt;, parses it to &lt;code&gt;u32&lt;/code&gt;, and handles a missing or invalid argument as shown above using &lt;code&gt;eprintln!&lt;/code&gt; and &lt;code&gt;std::process::exit(1)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;[ ] After the FizzBuzz lines, print &lt;code&gt;sum of multiples below N: X&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;[ ] At least 6 unit tests, including edge cases: 0, 1, 3, 5, 15, and a large number for &lt;code&gt;sum_of_multiples&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;cargo fmt --check &amp;amp;&amp;amp; cargo clippy -- -D warnings &amp;amp;&amp;amp; cargo test&lt;/code&gt; all pass.&lt;/li&gt;
&lt;li&gt;[ ] No &lt;code&gt;mut&lt;/code&gt; you don't need, and no &lt;code&gt;unwrap()&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Hints (read only when stuck)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;You can &lt;code&gt;match&lt;/code&gt; on a tuple: &lt;code&gt;match (n % 3, n % 5) { (0, 0) =&amp;gt; ..., ... }&lt;/code&gt;. Think about which arm order is correct and what &lt;code&gt;_&lt;/code&gt; patterns do inside a tuple.&lt;/li&gt;
&lt;li&gt;To turn a number into a &lt;code&gt;String&lt;/code&gt;, look up &lt;code&gt;to_string()&lt;/code&gt;. Notice every arm of a &lt;code&gt;match&lt;/code&gt; must have the same type.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;std::env::args().nth(1)&lt;/code&gt; returns an &lt;code&gt;Option&amp;lt;String&amp;gt;&lt;/code&gt;, which is either &lt;code&gt;Some(value)&lt;/code&gt; or &lt;code&gt;None&lt;/code&gt;. You can &lt;code&gt;match&lt;/code&gt; on it exactly like a &lt;code&gt;u16&lt;/code&gt; above.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;"42".parse::&amp;lt;u32&amp;gt;()&lt;/code&gt; returns a &lt;code&gt;Result&amp;lt;u32, ParseIntError&amp;gt;&lt;/code&gt;: either &lt;code&gt;Ok(n)&lt;/code&gt; or &lt;code&gt;Err(e)&lt;/code&gt;. Also handled with &lt;code&gt;match&lt;/code&gt;. We go deep on both in Lessons 3 and 4; for today pattern matching is enough.&lt;/li&gt;
&lt;li&gt;For &lt;code&gt;sum_of_multiples&lt;/code&gt;, &lt;code&gt;u64::from(x)&lt;/code&gt; widens a &lt;code&gt;u32&lt;/code&gt; losslessly. Write it first with a &lt;code&gt;for&lt;/code&gt; loop and a &lt;code&gt;mut&lt;/code&gt; total, then, as a stretch goal, as one iterator chain using &lt;code&gt;filter&lt;/code&gt;, &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;sum&lt;/code&gt; (look them up in &lt;code&gt;cargo doc --open&lt;/code&gt; or &lt;a href="https://doc.rust-lang.org/std/iter/trait.Iterator.html" rel="noopener noreferrer"&gt;doc.rust-lang.org/std&lt;/a&gt;).&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>beginners</category>
      <category>go</category>
      <category>rust</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Unveiling Linux Command's - sar</title>
      <dc:creator>Syam SV</dc:creator>
      <pubDate>Mon, 28 Aug 2023 05:08:57 +0000</pubDate>
      <link>https://dev.to/syamsv/unveiling-linux-commands-sar-42m1</link>
      <guid>https://dev.to/syamsv/unveiling-linux-commands-sar-42m1</guid>
      <description>&lt;p&gt;In the world of computers, the SAR (System Activity Reporter) command is like a magic tool. It helps us understand how our computer is doing and where it might need some help. In this article, we'll take a look at the SAR command and see how it can tell us interesting things about our computer.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is SAR?
&lt;/h2&gt;

&lt;p&gt;SAR stands for System Activity Reporter. It's like a detective that watches over our computer and takes notes about what it's doing. It looks at what's happening on our computer and makes reports about it. It can tell us things like how busy our computer is, how much memory it's using, how the network is behaving, and much more. It's like a data historian that keeps track of what our computer has been up to.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For detailed matrix information, please refer to &lt;a href="https://knowledge.broadcom.com/external/article/168067/sar-system-accounting-utility.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;* and &lt;a href="https://docs.oracle.com/cd/E36784_01/html/E36819/spmonitor-8.html#ADSYSenueh" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sar &lt;span class="o"&gt;[&lt;/span&gt; options &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &amp;lt;interval&amp;gt; &lt;span class="o"&gt;[&lt;/span&gt; &amp;lt;count&amp;gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sar &lt;span class="nt"&gt;-b&lt;/span&gt; 1 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sar &lt;span class="nt"&gt;-r&lt;/span&gt; 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SAR can do many helpful jobs for us. Let's look at some of them and see what they mean&lt;/p&gt;

&lt;blockquote&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Checking I/O and Transfer Rate
&lt;/h2&gt;

&lt;p&gt;Imagine your computer is sending and receiving data. SAR can tell us how busy it is doing that. It can count how many times it's doing these jobs and how much data is being sent and received every second.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sar &lt;span class="nt"&gt;-b&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &amp;lt;interval&amp;gt; &lt;span class="o"&gt;[&lt;/span&gt; &amp;lt;count&amp;gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sar &lt;span class="nt"&gt;-b&lt;/span&gt; 1 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Paging Statistics
&lt;/h2&gt;

&lt;p&gt;Sometimes, our computer needs to get information from the hard drive. This is called paging. SAR can tell us how often this happens and how much data is being moved between the hard drive and the computer's memory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sar &lt;span class="nt"&gt;-B&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &amp;lt;interval&amp;gt; &lt;span class="o"&gt;[&lt;/span&gt; &amp;lt;count&amp;gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sar &lt;span class="nt"&gt;-B&lt;/span&gt; 1 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Network Numbers
&lt;/h2&gt;

&lt;p&gt;If our computer is connected to the internet, SAR can tell us how much data is going in and out. It can show us how many packets of data are being sent and received. This helps us understand if our internet connection is fast or slow.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sar &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;options] &lt;span class="o"&gt;[&lt;/span&gt; &amp;lt;interval&amp;gt; &lt;span class="o"&gt;[&lt;/span&gt; &amp;lt;count&amp;gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sar &lt;span class="nt"&gt;-n&lt;/span&gt; DEV 1 10
sar &lt;span class="nt"&gt;-n&lt;/span&gt; TCP,UDP 1 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Load and Queue
&lt;/h2&gt;

&lt;p&gt;When our computer is doing many things at once, it has a "load." SAR can tell us how heavy this load is. It can also tell us how many things are waiting to be done. This is like knowing how many people are waiting in line at a store.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sar &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &amp;lt;interval&amp;gt; &lt;span class="o"&gt;[&lt;/span&gt; &amp;lt;count&amp;gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sar &lt;span class="nt"&gt;-q&lt;/span&gt; 1 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Memory and Swap Info
&lt;/h2&gt;

&lt;p&gt;Our computer uses memory to work. SAR can show us how much of this memory is being used. It can also tell us if the computer is using "swap space," which is like extra memory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sar &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &amp;lt;interval&amp;gt; &lt;span class="o"&gt;[&lt;/span&gt; &amp;lt;count&amp;gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sar &lt;span class="nt"&gt;-r&lt;/span&gt; 1 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  CPU Usage
&lt;/h2&gt;

&lt;p&gt;The "brain" of our computer is called the CPU. SAR can tell us how busy the CPU is. It can say if it's mostly being used by programs, or if it's waiting for something to happen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sar &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &amp;lt;interval&amp;gt; &lt;span class="o"&gt;[&lt;/span&gt; &amp;lt;count&amp;gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sar &lt;span class="nt"&gt;-u&lt;/span&gt; 1 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Page Swapping
&lt;/h2&gt;

&lt;p&gt;Sometimes, the computer needs to exchange data quickly. This is called "swapping." SAR can tell us if this is happening a lot and if it's causing any problems.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sar &lt;span class="nt"&gt;-W&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &amp;lt;interval&amp;gt; &lt;span class="o"&gt;[&lt;/span&gt; &amp;lt;count&amp;gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sar &lt;span class="nt"&gt;-W&lt;/span&gt; 1 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;SAR is like a helpful friend that watches over our computer. It tells us all sorts of things about what's happening inside. Whether it's how busy our computer is, how much memory it's using, or how well the internet is working, SAR gives us answers. So, the next time you're curious about how your computer is performing, remember to ask SAR! Keep in mind that this article provides a simplified overview of SAR, and if you're interested in diving deeper, be sure to refer back to the detailed explanations above.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>terminal</category>
      <category>bash</category>
    </item>
    <item>
      <title>Unveiling Linux Command's - dmesg</title>
      <dc:creator>Syam SV</dc:creator>
      <pubDate>Thu, 24 Aug 2023 12:03:42 +0000</pubDate>
      <link>https://dev.to/syamsv/unveiling-linux-commands-dmesg-3npd</link>
      <guid>https://dev.to/syamsv/unveiling-linux-commands-dmesg-3npd</guid>
      <description>&lt;p&gt;&lt;code&gt;dmesg&lt;/code&gt;, short for "diagnostic messages" is a command-line utility in Linux that provides access to the kernel's ring buffer. This buffer stores messages generated by the Linux kernel during the boot process and while the system is running. These messages encompass a wide range of information, including device driver status, hardware initialization, and error messages. Users can rely on the dmesg command for several key reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Boot Process Analysis&lt;/strong&gt;: When a Linux system boots up, a plethora of hardware components and device drivers are initialized. In case of any failures or warnings during this process, dmesg becomes your go-to tool. Running &lt;code&gt;dmesg&lt;/code&gt; immediately after boot can help you identify hardware issues, driver failures, and other critical information.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kernel Error Diagnosis&lt;/strong&gt;: Kernel messages displayed by &lt;code&gt;dmesg&lt;/code&gt; include errors, warnings, and information about kernel modules. When something goes wrong at the kernel level, dmesg can provide insights into the root cause of the issue, helping you diagnose and rectify the problem promptly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Driver Debugging&lt;/strong&gt;: &lt;code&gt;dmesg&lt;/code&gt; allows you to examine the interaction between your drivers and the kernel, aiding in debugging and improving driver performance.&lt;/li&gt;
&lt;li&gt;and more ...&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Basic Usage
&lt;/h3&gt;

&lt;p&gt;The simplest way to use dmesg is by running the command without any options&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dmesg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will display the most recent kernel messages, starting from the end of the ring buffer&lt;/p&gt;

&lt;h3&gt;
  
  
  Severity based filtering
&lt;/h3&gt;

&lt;p&gt;You can filter messages based on their severity levels using the &lt;code&gt;-l&lt;/code&gt; or &lt;code&gt;--level&lt;/code&gt;option. The severity levels include &lt;code&gt;emerg&lt;/code&gt; (emergency), &lt;code&gt;alert&lt;/code&gt;, &lt;code&gt;crit&lt;/code&gt; (critical), &lt;code&gt;err&lt;/code&gt; (error), &lt;code&gt;warn&lt;/code&gt; (warning), &lt;code&gt;notice&lt;/code&gt;, &lt;code&gt;info&lt;/code&gt;, and &lt;code&gt;debug&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dmesg &lt;span class="nt"&gt;-l&lt;/span&gt; err,warn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Continuous monitoring
&lt;/h3&gt;

&lt;p&gt;To monitor the kernel messages in real-time as new messages are logged, you can use the -w or --follow option&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dmesg &lt;span class="nt"&gt;-w&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Clearing the kernel ring buffer
&lt;/h3&gt;

&lt;p&gt;Sometimes, you might want to clear the ring buffer, such as after diagnosing an issue and wanting to start with a clean slate. This can be done using the &lt;code&gt;-c&lt;/code&gt; or &lt;code&gt;--clear&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dmesg &lt;span class="nt"&gt;-c&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;dmesg&lt;/code&gt; command is a versatile tool that empowers system administrators to gain insights into the inner workings of the Linux kernel. By mastering its various options, you can effectively diagnose issues, analyze system behavior, and ensure the stability and reliability of your Linux systems. Whether you're troubleshooting boot failures, managing devices and drivers, or debugging kernel-level problems, &lt;code&gt;dmesg&lt;/code&gt; remains an invaluable asset in your system administration toolkit&lt;/p&gt;

</description>
      <category>linux</category>
      <category>bash</category>
      <category>terminal</category>
    </item>
    <item>
      <title>Formatting &amp; Mounting Storage Volumes</title>
      <dc:creator>Syam SV</dc:creator>
      <pubDate>Thu, 24 Aug 2023 04:48:56 +0000</pubDate>
      <link>https://dev.to/syamsv/formatting-mounting-storage-volumes-af</link>
      <guid>https://dev.to/syamsv/formatting-mounting-storage-volumes-af</guid>
      <description>&lt;h2&gt;
  
  
  Listing and Identifying Storage Devices
&lt;/h2&gt;

&lt;p&gt;let's begin by learning how to list and identify the storage devices attached to your system. Using the lsblk command, you can get a comprehensive list of all the block devices, such as hard drives and USB flash drives, connected to your machine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;lsblk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each storage device is uniquely identified by a device name like sda, sdb, etc., which will help you interact with them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a Partition Table and Partitions with fdisk
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;fdisk&lt;/code&gt; is a powerful command-line tool that allows you to create and manage partition tables on your storage devices. In this section, it'll walk you through the process of creating a partition table, creating partitions, and writing the changes to the disk.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Be cautious when using fdisk as it directly modifies the disk's partition table. Any incorrect actions may lead to data loss. Make sure you have a backup of your important data before proceeding.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Identify the Disk Device&lt;br&gt;
Before using fdisk, you need to identify the disk device you want to partition. To list all available disks, use the lsblk command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;lsblk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Identify the disk you want to partition, such as /dev/sdX (e.g., /dev/sda, /dev/sdb, etc.), where "X" is the specific letter assigned to the disk by the system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Launching fdisk
&lt;/h2&gt;

&lt;p&gt;To start partitioning the disk, run fdisk with the chosen disk device:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;fdisk /dev/sdX
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;/dev/sdX&lt;/code&gt; with the appropriate disk identifier.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a New Partition Table
&lt;/h3&gt;

&lt;p&gt;If the disk is not yet partitioned or you want to create a new partition table, follow these steps:&lt;br&gt;
a. Press &lt;code&gt;g&lt;/code&gt; to create a new GPT (GUID Partition Table) or &lt;code&gt;m&lt;/code&gt; to create a new MSDOS (MBR) partition table.&lt;/p&gt;
&lt;h3&gt;
  
  
  Creating Partitions
&lt;/h3&gt;

&lt;p&gt;To create a new partition, follow these steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Press n to start creating a new partition.&lt;/li&gt;
&lt;li&gt;Specify the partition number (e.g., 1, 2, etc.).&lt;/li&gt;
&lt;li&gt;Specify the starting sector (press Enter for the default).&lt;/li&gt;
&lt;li&gt;Specify the ending sector. You can either:&lt;/li&gt;
&lt;li&gt;Use a specific size (e.g., +1G for 1 gigabyte) or&lt;/li&gt;
&lt;li&gt;Press Enter to use the remaining space on the disk.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Formatting a Storage Device
&lt;/h2&gt;

&lt;p&gt;After creating partitions, you'll typically need to format them with a file system before using them. Once you've identified the storage device you want to utilize, you might need to format it with a specific file system type before you can use it. For Linux, the most common file system types are ext4, while for cross-platform compatibility with Windows, you can use exFAT. Here are the commands to format the partition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;mkfs.ext4 /dev/&amp;lt;device_partition&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;mkfs.exfat &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"label"&lt;/span&gt; /dev/&amp;lt;device_partition&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace  with the appropriate partition identifier, such as /dev/sdb1, for your device.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mounting the Storage Volume
&lt;/h2&gt;

&lt;p&gt;After formatting the partition, you can mount it to make it accessible within the file system. You have the flexibility to mount the partition to any folder you like, but commonly used mount points are /mnt for permanent volumes and /media for temporary ones.&lt;/p&gt;

&lt;p&gt;Here's how you can mount the partition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;mount /dev/&amp;lt;device_partition&amp;gt; /&amp;lt;mount_path&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we can see each option can be supplied along with a value when mounting the device.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;mount &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;uid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;uid&amp;gt;,gid&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;group_id&amp;gt; /dev/&amp;lt;device_partition&amp;gt; /&amp;lt;mount_path&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace  with the directory where you want to access the storage volume.&lt;/p&gt;

&lt;h2&gt;
  
  
  Analyzing Disk Usage with ncdu
&lt;/h2&gt;

&lt;p&gt;Now, let's introduce you to a powerful storage management tool called ncdu. In case it's not already installed, you might need to install it first. For Fedora and Centos use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;dnf &lt;span class="nb"&gt;install &lt;/span&gt;ncdu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For Debian-based systems, use apt instead of dnf.&lt;/p&gt;

&lt;p&gt;Once installed, you can use ncdu to analyze disk usage on your system. This tool provides a detailed breakdown of files and directories consuming the most space. To use ncdu, simply run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ncdu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will display the disk usage starting from your current directory. You can navigate through the results, drill down into directories, and identify which files are taking up the most space. This tool is incredibly handy when you need to reclaim storage space on your system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automating Mounts with /etc/fstab
&lt;/h2&gt;

&lt;p&gt;For those looking to automate the process of mounting storage volumes during system boot, the /etc/fstab file comes to the rescue. However, editing this file requires caution, as mistakes can prevent your system from booting correctly.&lt;/p&gt;

&lt;p&gt;The /etc/fstab file allows you to specify the devices and mount points you want to mount automatically at startup, using UUIDs or device names to identify the storage volumes. Please note that editing this file requires an understanding of the correct syntax and should be approached carefully. If you're unsure, it's best to seek expert guidance or create proper backups before making any changes.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>disk</category>
    </item>
    <item>
      <title>Firewalld Basics and Usage with firewall-cmd:</title>
      <dc:creator>Syam SV</dc:creator>
      <pubDate>Mon, 21 Aug 2023 05:54:09 +0000</pubDate>
      <link>https://dev.to/syamsv/firewalld-basics-and-usage-with-firewall-cmd-46if</link>
      <guid>https://dev.to/syamsv/firewalld-basics-and-usage-with-firewall-cmd-46if</guid>
      <description>&lt;p&gt;Firewalld is a robust firewall management tool available for various Linux distributions. It provides a user-friendly interface for managing iptables, the packet filtering system within the Linux kernel. we will walk the fundamentals of setting up and configuring Firewalld using the firewall-cmd command-line utility. &lt;/p&gt;

&lt;p&gt;Detailed documentation about Firewalld can be found at the provided &lt;a href="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/security_guide/sec-using_firewalls#sec-Getting_started_with_firewalld" rel="noopener noreferrer"&gt;link&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic Concepts in Firewalld
&lt;/h2&gt;

&lt;p&gt;Firewalld introduces the concept of "zones," which dictate the behavior of the firewall based on the level of trust associated with the networks your system is connected to. Zones provide flexibility, enabling you to tailor rules depending on your environment. For instance, a laptop might need stricter rules on a public WiFi network while being more relaxed on a trusted home network. Predefined zones range from least trusted (e.g., drop, block) to most trusted (trusted, internal). The firewall-cmd utility facilitates the management of these zones.&lt;/p&gt;

&lt;h2&gt;
  
  
  Zones in Firewalld
&lt;/h2&gt;

&lt;p&gt;In Firewalld, zones are a crucial concept that dictates how the firewall treats network traffic based on the level of trust associated with the networks your system is connected to. Each zone defines a set of rules that determine which traffic is allowed and which is denied. Firewalld allows you to assign different interfaces to different zones, allowing for a flexible approach to network security. Zones are particularly useful for systems that might move between different networks, such as laptops, and for segmenting trust levels on servers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Default Zones
&lt;/h2&gt;

&lt;p&gt;Firewalld comes with a set of predefined zones, each with a different level of trust. Here are the default zones provided by Firewalld, listed from least trusted to most trusted:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;drop&lt;/strong&gt; : This is the lowest level of trust. All incoming connections are dropped without a reply, and only outgoing connections are possible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;block&lt;/strong&gt; : Similar to "drop," incoming connections are rejected with an ICMP message. Outgoing connections are allowed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;public&lt;/strong&gt; : Represents public, untrusted networks. You allow selected incoming connections on a case-by-case basis. This zone is useful for public Wi-Fi networks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;external&lt;/strong&gt; : Designed for external networks when your system is acting as a gateway. It configures NAT masquerading to keep your internal network private yet reachable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;internal&lt;/strong&gt; : Used for the internal side of a gateway. This zone assumes more trustworthiness for the computers and allows some additional services.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;dmz&lt;/strong&gt; : Used for computers located in a DMZ (isolated computers that won't access the rest of your network). Only certain incoming connections are allowed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;work&lt;/strong&gt; : Meant for work machines. You trust most computers on the network, and a few more services might be allowed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;home&lt;/strong&gt; : Suitable for home environments. It implies a higher level of trust among computers, and more services will be accepted.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;trusted&lt;/strong&gt; : The most open option, to be used sparingly. It trusts all machines in the network.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Targets
&lt;/h2&gt;

&lt;p&gt;Within each zone, there's a concept called "target." A target defines the default behavior of the firewall for incoming traffic. These targets are used to specify what happens when an incoming connection matches the rules of the zone. Here are the common targets used in Firewalld:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;default&lt;/strong&gt; : This is the default target. It allows the default behavior for the zone, which can be controlled further through rule definitions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;accept&lt;/strong&gt; : Incoming traffic is accepted without restrictions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;drop&lt;/strong&gt; : Incoming traffic is dropped without any response.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;reject&lt;/strong&gt; : Similar to "drop," but the system responds with an ICMP error message.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;masquerade&lt;/strong&gt; : Used for source NAT (Network Address Translation) to modify the source IP address of outgoing packets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;redirect&lt;/strong&gt; : Used for destination NAT to redirect incoming packets to a different IP address and port.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Rule Permanence
&lt;/h2&gt;

&lt;p&gt;Firewalld rules can be immediate (active during the current session) or permanent (persist after reboot). The --permanent flag designates permanent rules that apply across reboots. This separation allows testing rules in the current session before making them permanent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing and Enabling Firewalld
&lt;/h2&gt;

&lt;p&gt;To install Firewalld, use your package manager (e.g., &lt;code&gt;sudo apt install firewalld&lt;/code&gt;). After installation, enable the service to start at boot:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;firewalld
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's recommended to configure your firewall rules and test them before enabling this behavior to avoid potential issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verifying Firewalld Status
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Check if Firewalld is up and running:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;firewall-cmd &lt;span class="nt"&gt;--state&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A "running" status indicates that the firewall is operational with the default configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exploring Current Firewall Rules
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt; Get the default zone:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;firewall-cmd &lt;span class="nt"&gt;--get-default-zone&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt; List active zones:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;firewall-cmd &lt;span class="nt"&gt;--get-active-zones&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt; View rules for a zone (e.g., "public"):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;firewall-cmd &lt;span class="nt"&gt;--zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;public &lt;span class="nt"&gt;--list-all&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt; To move an interface to a different zone during the current session:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;firewall-cmd &lt;span class="nt"&gt;--zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;new-zone &lt;span class="nt"&gt;--change-interface&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;interface-name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Adjusting Default Zone
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Change the default zone:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;firewall-cmd &lt;span class="nt"&gt;--set-default-zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;new-default-zone
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Adding Services to Zones
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt; List available services:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;firewall-cmd &lt;span class="nt"&gt;--get-services&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt; Add a service to a zone (e.g., "public"):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;firewall-cmd &lt;span class="nt"&gt;--zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;public &lt;span class="nt"&gt;--add-service&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;service-name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt; Make the change permanent:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;firewall-cmd &lt;span class="nt"&gt;--zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;public &lt;span class="nt"&gt;--permanent&lt;/span&gt; &lt;span class="nt"&gt;--add-service&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;service-name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Opening Ports for Specific Applications
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt; Open a port for a zone (e.g., "public"):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;firewall-cmd &lt;span class="nt"&gt;--zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;public &lt;span class="nt"&gt;--add-port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;port/protocol
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt; Open a port range:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;firewall-cmd &lt;span class="nt"&gt;--zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;public &lt;span class="nt"&gt;--add-port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;start-end/protocol
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Defining Custom Services
&lt;/h2&gt;

&lt;p&gt;Copy an existing service definition (e.g., SSH) to create a custom service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo cp&lt;/span&gt; /usr/lib/firewalld/services/ssh.xml /etc/firewalld/services/custom-service.xml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Modify the custom service definition in /etc/firewalld/services/custom-service.xml.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Reload the firewall to apply changes:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;firewall-cmd &lt;span class="nt"&gt;--reload&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating Your Own Zones
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Create a new zone (e.g., "custom-zone"):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;firewall-cmd &lt;span class="nt"&gt;--permanent&lt;/span&gt; &lt;span class="nt"&gt;--new-zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;custom-zone
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Reload the firewall to activate the new zone:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;firewall-cmd &lt;span class="nt"&gt;--reload&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Assign interfaces to the new zone (if interface is not already assigned ):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;firewall-cmd &lt;span class="nt"&gt;--zone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;custom-zone &lt;span class="nt"&gt;--add-interface&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;interface-name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Firewalld provides an effective way to manage firewall rules using zones and services. By understanding these concepts and the usage of the firewall-cmd utility, you can create tailored firewall configurations that cater to your network environment. Additionally, the installation of Firewalld with nftables enhances your firewall capabilities, contributing to improved security and network management.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>firewall</category>
      <category>terminal</category>
    </item>
    <item>
      <title>Unveiling Linux Command's - rsync</title>
      <dc:creator>Syam SV</dc:creator>
      <pubDate>Mon, 21 Aug 2023 05:42:15 +0000</pubDate>
      <link>https://dev.to/syamsv/unveiling-linux-commands-rsync-1o5</link>
      <guid>https://dev.to/syamsv/unveiling-linux-commands-rsync-1o5</guid>
      <description>&lt;p&gt;Rsync (Remote Sync) is a command-line utility used for efficiently transferring and synchronizing files and directories between local and remote systems. It uses an algorithm to minimize the amount of data copied by only moving the portions of files that have changed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic Syntax:
&lt;/h2&gt;

&lt;p&gt;The basic syntax of the rsync command is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rsync &lt;span class="o"&gt;[&lt;/span&gt;options] &lt;span class="nb"&gt;source &lt;/span&gt;destination
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;source: The source directory or file you want to transfer.&lt;/li&gt;
&lt;li&gt;destination: The target directory or location where you want to copy the source.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Commonly Used Options:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;-a or --archive: This option enables archive mode, which preserves file permissions, ownership, timestamps, and more. It's often used for full data synchronization.&lt;/li&gt;
&lt;li&gt;-v or --verbose: Enables verbose output, showing details about the files being transferred.&lt;/li&gt;
&lt;li&gt;-r or --recursive: Enables recursive mode, ensuring that all subdirectories and their contents are transferred.&lt;/li&gt;
&lt;li&gt;--dry-run: Simulates the transfer without actually performing it. Useful for previewing what would be copied.&lt;/li&gt;
&lt;li&gt;--delete: Deletes files at the destination that are not present in the source. Useful for maintaining exact synchronization.&lt;/li&gt;
&lt;li&gt;-z or --compress: Compresses files during transfer, which can improve transfer speed over slow connections.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use Cases and Examples:
&lt;/h3&gt;

&lt;h2&gt;
  
  
  Local Copy:
&lt;/h2&gt;

&lt;p&gt;To copy files or directories locally, use the basic syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rsync &lt;span class="nt"&gt;-av&lt;/span&gt; source_directory/ destination_directory/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Remote Copy:
&lt;/h2&gt;

&lt;p&gt;To copy files or directories from a local system to a remote server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rsync &lt;span class="nt"&gt;-av&lt;/span&gt; source_directory/ user@remote_server:/path/to/destination/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Remote Copy with SSH:
&lt;/h2&gt;

&lt;p&gt;To copy files or directories from a local system to a remote server over SSH:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rsync &lt;span class="nt"&gt;-av&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"ssh -i /path/to/key.pem"&lt;/span&gt; source_directory/ user@remote_server:/path/to/destination/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rsync &lt;span class="nt"&gt;-av&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; ssh source_directory/ user@remote_server:/path/to/destination/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Exclude Files or Directories:
&lt;/h2&gt;

&lt;p&gt;To exclude specific files or directories from the transfer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rsync &lt;span class="nt"&gt;-av&lt;/span&gt; &lt;span class="nt"&gt;--exclude&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"file_to_exclude"&lt;/span&gt; source_directory/ destination_directory/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Dry Run:
&lt;/h2&gt;

&lt;p&gt;To preview the transfer without actually copying:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rsync &lt;span class="nt"&gt;-av&lt;/span&gt; &lt;span class="nt"&gt;--dry-run&lt;/span&gt; source_directory/ destination_directory/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Delete Unwanted Files:
&lt;/h3&gt;

&lt;p&gt;To remove files at the destination that are not in the source:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rsync &lt;span class="nt"&gt;-av&lt;/span&gt; &lt;span class="nt"&gt;--delete&lt;/span&gt; source_directory/ destination_directory/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Compressed Transfer:
&lt;/h2&gt;

&lt;p&gt;To enable compression during transfer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rsync &lt;span class="nt"&gt;-avz&lt;/span&gt; source_directory/ user@remote_server:/path/to/destination/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Maintain Metadata:
&lt;/h2&gt;

&lt;p&gt;To ensure metadata consistency during transfers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rsync &lt;span class="nt"&gt;-av&lt;/span&gt; source_directory/ destination_directory/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Synchronize Remote Directory:
&lt;/h2&gt;

&lt;p&gt;To synchronize a remote directory with a local one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rsync &lt;span class="nt"&gt;-av&lt;/span&gt; user@remote_server:/path/to/source_directory/ local_destination/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Copying Remote to Local:
&lt;/h2&gt;

&lt;p&gt;To copy files from a remote server to a local machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rsync &lt;span class="nt"&gt;-av&lt;/span&gt; user@remote_server:/path/to/source_directory/ local_destination/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Backup option in Rsync
&lt;/h2&gt;

&lt;p&gt;Rsync’s --backup option can be used to store backups of important files. It’s used in along with the --backup-dir option, which specifies the directory where the backup files should be stored&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rsync &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="nt"&gt;--delete&lt;/span&gt; &lt;span class="nt"&gt;--backup&lt;/span&gt; &lt;span class="nt"&gt;--backup-dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/path/to/backups /path/to/source destination
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion:
&lt;/h2&gt;

&lt;p&gt;Rsync is a versatile tool for efficiently transferring and synchronizing files between local and remote systems. It provides various options that allow you to control the behavior of the transfer, maintain metadata consistency, exclude files, and even simulate transfers before executing them. Its ability to work over SSH ensures secure data transfers across networks, making it an essential tool for managing and backing up data in a Linux environment.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>bash</category>
      <category>terminal</category>
    </item>
    <item>
      <title>Unveiling Linux Command's - usermod</title>
      <dc:creator>Syam SV</dc:creator>
      <pubDate>Mon, 21 Aug 2023 05:39:30 +0000</pubDate>
      <link>https://dev.to/syamsv/unveiling-linux-commands-usermod-476</link>
      <guid>https://dev.to/syamsv/unveiling-linux-commands-usermod-476</guid>
      <description>&lt;p&gt;The usermod command in Linux is a powerful tool that helps system administrators modify various attributes of user accounts. These attributes include user groups, home directories, usernames, and more. It's like a tool that lets you change how a user works with the system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding Users to Groups
&lt;/h2&gt;

&lt;p&gt;Imagine you have a Linux server where you need to give specific users special permissions. This is where usermod comes in handy. You can add a user to an existing group using this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; &amp;lt;group-name&amp;gt; &amp;lt;username&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For instance, if you want to add a user named "alice" to the "developers" group, the command would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; developers alice
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Moving User Home Directories
&lt;/h2&gt;

&lt;p&gt;Home directories are where users store their personal files and settings. If you need to move a user's home directory to a different location, usermod can help:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-d&lt;/span&gt; &amp;lt;new-directory&amp;gt; &amp;lt;username&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Suppose you want to move the home directory of the user "bob" to "/newhome":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-d&lt;/span&gt; /newhome bob
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Changing Usernames
&lt;/h2&gt;

&lt;p&gt;Usernames might need to be changed for various reasons, like rebranding or making usernames consistent across systems. Usermod makes this process simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-l&lt;/span&gt; &amp;lt;new-username&amp;gt; &amp;lt;old-username&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, if you want to change the username "olduser" to "newuser":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-l&lt;/span&gt; newuser olduser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  User Expiration
&lt;/h2&gt;

&lt;p&gt;Security is crucial in user management. With usermod, you can set an expiration date for a user to enhance security:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-e&lt;/span&gt; &amp;lt;expiration-date&amp;gt; &amp;lt;username&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Suppose you want the password for the user "jane" to expire on January 1, 2024:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-e&lt;/span&gt; 2024-01-01 jane
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Locking and unlocking user
&lt;/h2&gt;

&lt;p&gt;Locking a user account prevents the user from accessing the system. Locking can be helpful in certain situations. To lock a user account using the usermod command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-L&lt;/span&gt; &amp;lt;username&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unlocking a user account is equally important, as you may need to restore access after resolving a situation. To unlock a user account:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-U&lt;/span&gt; &amp;lt;username&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In the world of Linux system administration, the usermod command plays a crucial role in managing user accounts effectively. Its ability to modify user attributes like groups, home directories, usernames, and password expiration dates empowers administrators to maintain a secure and organized system.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>terminal</category>
      <category>bash</category>
    </item>
    <item>
      <title>Unveiling Linux Command's - scp (Secure Copy)</title>
      <dc:creator>Syam SV</dc:creator>
      <pubDate>Mon, 21 Aug 2023 05:37:11 +0000</pubDate>
      <link>https://dev.to/syamsv/unveiling-linux-commands-scp-secure-copy-1k5c</link>
      <guid>https://dev.to/syamsv/unveiling-linux-commands-scp-secure-copy-1k5c</guid>
      <description>&lt;p&gt;SCP (Secure Copy) is a command-line utility in Unix-like operating systems that enables secure and efficient file transfers between a local and remote host or between two remote hosts. It is built on top of the SSH protocol, ensuring data confidentiality and integrity during the transfer process. SCP is widely used for transferring files and directories in a secure manner.&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic Syntax:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp &lt;span class="o"&gt;[&lt;/span&gt;options] &lt;span class="nb"&gt;source &lt;/span&gt;destination
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Common Options:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;-r: Recursively copy directories and their contents.&lt;/li&gt;
&lt;li&gt;-p: Preserve modification times, access times, and modes from the original files.&lt;/li&gt;
&lt;li&gt;-P port: Specify a different port for SSH. Default is 22.&lt;/li&gt;
&lt;li&gt;-i identity_file: Use an identity file (private key) for authentication.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Some common usecases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Copying a File from Local to Remote:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp file.txt user@remotehost:/path/to/destination/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This copies the local file file.txt to the remote server at the specified path.&lt;/p&gt;

&lt;h3&gt;
  
  
  Copying a File from Remote to Local:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp user@remotehost:/path/to/source/file.txt /local/destination/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This copies the remote file file.txt to the local machine at the specified path.&lt;/p&gt;

&lt;h3&gt;
  
  
  Copying a Directory Recursively:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp &lt;span class="nt"&gt;-r&lt;/span&gt; directory/ user@remotehost:/path/to/destination/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The -r option allows you to copy the entire directory and its contents.&lt;/p&gt;

&lt;h3&gt;
  
  
  Copying with a Different Port:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp &lt;span class="nt"&gt;-P&lt;/span&gt; 2222 file.txt user@remotehost:/path/to/destination/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command specifies a non-default SSH port (2222) for the transfer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Preserving File Metadata:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp &lt;span class="nt"&gt;-p&lt;/span&gt; file.txt user@remotehost:/path/to/destination/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The -p option maintains the original modification times and permissions of the file.&lt;/p&gt;

&lt;p&gt;Copying Between Two Remote Hosts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp user1@remotehost1:/file.txt user2@remotehost2:/path/to/destination/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This copies a file from one remote host to another.&lt;/p&gt;

&lt;p&gt;Using Identity File for Authentication:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp &lt;span class="nt"&gt;-i&lt;/span&gt; ~/.ssh/my_private_key.pem file.txt user@remotehost:/path/to/destination/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The -i option specifies the private key for SSH authentication.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparison with Other Tools:
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;SCP&lt;/strong&gt; vs. &lt;strong&gt;rsync&lt;/strong&gt; : SCP is suitable for simple one-time transfers, while rsync is more versatile for syncing and incremental transfers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion:
&lt;/h2&gt;

&lt;p&gt;The SCP command provides a secure and efficient way to transfer files and directories between local and remote hosts. Its use cases include simple file transfers, recursive directory transfers, specifying custom SSH ports, preserving file metadata, and more. By leveraging the SSH protocol, SCP ensures data security and integrity during the transfer process.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>terminal</category>
      <category>bash</category>
    </item>
    <item>
      <title>Unveiling Linux Command's - useradd &amp; adduser</title>
      <dc:creator>Syam SV</dc:creator>
      <pubDate>Mon, 21 Aug 2023 05:32:11 +0000</pubDate>
      <link>https://dev.to/syamsv/unveiling-linux-commands-useradd-adduser-1pa1</link>
      <guid>https://dev.to/syamsv/unveiling-linux-commands-useradd-adduser-1pa1</guid>
      <description>&lt;p&gt;When it comes to managing user accounts on a Linux system, two commonly used commands are &lt;code&gt;useradd&lt;/code&gt; and &lt;code&gt;adduser&lt;/code&gt;. While both commands are used to create user accounts, they have distinct differences in terms of flexibility, user-friendliness, and functionalities. In this blog post, we'll delve into the nuances of each command and provide step-by-step guides on how to use them.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;useradd&lt;/code&gt; Command
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;useradd&lt;/code&gt; command is a fundamental utility for creating user accounts on Linux systems. It's a low-level command that allows system administrators to create new users with specific configurations. However, using &lt;code&gt;useradd&lt;/code&gt; requires you to set various options manually, which can be more complex and time-consuming, especially for beginners.&lt;/p&gt;

&lt;p&gt;To create a user named "newuser," use the following command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;useradd newuser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set a password for the new user&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;passwd newuser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To specify the home directory for the user, use the &lt;code&gt;-d&lt;/code&gt; option&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;useradd &lt;span class="nt"&gt;-d&lt;/span&gt; /home/customdir newuser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assign a specific user ID (UID) using the &lt;code&gt;-u&lt;/code&gt; option (replace &lt;code&gt;UID&lt;/code&gt; with the desired ID):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;useradd &lt;span class="nt"&gt;-u&lt;/span&gt; UID newuser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To set an expiration date for the user account, use the &lt;code&gt;-e&lt;/code&gt; option followed by the date in YYYY-MM-DD format&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;useradd &lt;span class="nt"&gt;-e&lt;/span&gt; 2023-12-31 newuser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;adduser&lt;/code&gt; Command
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;adduser&lt;/code&gt; command is a higher-level utility designed to simplify the process of adding new user accounts. It prompts the user with a series of questions, allowing for interactive configuration. This makes it more user-friendly and suitable for those who are less familiar with command-line options&lt;/p&gt;

&lt;p&gt;To start the interactive user creation process, type&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;adduser newuser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command will prompt you to set a password, full name, phone number, etc., for the new user. You can specify additional information such as the home directory, user groups, and expiration date for the account&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In summary, both the &lt;code&gt;useradd&lt;/code&gt; and &lt;code&gt;adduser&lt;/code&gt; commands serve the purpose of creating user accounts on Linux systems. The choice between them depends on your level of familiarity with command-line options and the degree of user interaction you desire. If you're comfortable with configuring options manually, &lt;code&gt;useradd&lt;/code&gt; offers fine-grained control. On the other hand, if you prefer a more user-friendly and interactive approach, &lt;code&gt;adduser&lt;/code&gt; is a better choice.&lt;/p&gt;

&lt;p&gt;Regardless of the command you choose, managing user accounts is a critical aspect of Linux system administration. Select the command that aligns with your needs and expertise to efficiently create and manage user accounts on your system.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>terminal</category>
      <category>bash</category>
    </item>
    <item>
      <title>Unveiling Linux Command's - find</title>
      <dc:creator>Syam SV</dc:creator>
      <pubDate>Sat, 19 Aug 2023 14:28:13 +0000</pubDate>
      <link>https://dev.to/syamsv/unveiling-linux-commands-find-5ffg</link>
      <guid>https://dev.to/syamsv/unveiling-linux-commands-find-5ffg</guid>
      <description>&lt;p&gt;Searching for files on your Linux system can sometimes feel like searching for a needle in a haystack. The &lt;code&gt;find&lt;/code&gt; command is here to make your file-finding tasks easy. In this post, we'll walk you through various scenarios where the &lt;code&gt;find&lt;/code&gt; command becomes very useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding files by name
&lt;/h2&gt;

&lt;p&gt;Ever found yourself hunting for a file but forgetting where you stashed it? The &lt;code&gt;find&lt;/code&gt; command can help you pinpoint it. When you're in your terminal, type&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;find /path/to/search &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"filename"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just replace &lt;code&gt;/path/to/search&lt;/code&gt; with your starting directory and &lt;code&gt;filename&lt;/code&gt; with the elusive file's name.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding files by size
&lt;/h2&gt;

&lt;p&gt;Sometimes you're dealing with large files, and sometimes it's the tiny ones causing a stir. &lt;code&gt;find&lt;/code&gt; can help with that too! To locate files based on their size, use&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;find /path/to/search &lt;span class="nt"&gt;-size&lt;/span&gt; +size_unit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace&lt;code&gt;/path/to/search&lt;/code&gt; with your directory and size_unit with the size you're after (like &lt;code&gt;10M&lt;/code&gt; for 10 megabytes). To find small files, use - instead of +.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding files by user
&lt;/h2&gt;

&lt;p&gt;Who's the owner of that file? &lt;code&gt;find&lt;/code&gt; can answer that. To discover files owned by a specific user or group&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;find /path/to/search &lt;span class="nt"&gt;-user&lt;/span&gt; username
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace /path/to/search with your directory and username with the owner's name. Similar to the user scenario, you can also use &lt;code&gt;-group groupname&lt;/code&gt; to find files owned by a particular group.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding files by permission
&lt;/h2&gt;

&lt;p&gt;Permissions can be quite the puzzle. But &lt;code&gt;find&lt;/code&gt;can help you unravel it. To identify files with specific permissions, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;find /path/to/search &lt;span class="nt"&gt;-perm&lt;/span&gt; permissions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;/path/to/search&lt;/code&gt; is your directory, and &lt;code&gt;permissions&lt;/code&gt; are the numeric values (like 755 for read, write, and execute). If you want files with any of the specified permission bits, use -perm /permissions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding files by date and time
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;find&lt;/code&gt; command help you to navigate through time and locate files based on their access, modification, or change times.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;find /path/to/search &lt;span class="nt"&gt;-atime&lt;/span&gt;/-ctime/-mtime +/-time_unit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;/path/to/search&lt;/code&gt; with your directory, pick &lt;code&gt;atime&lt;/code&gt;, &lt;code&gt;ctime&lt;/code&gt;, or &lt;code&gt;mtime&lt;/code&gt;, and adjust &lt;code&gt;+/-time_unit&lt;/code&gt; to specify the time frame.&lt;/p&gt;

&lt;p&gt;Following are some example cases to understand &lt;/p&gt;

&lt;h3&gt;
  
  
  Find Recently Modified Files in the a directory
&lt;/h3&gt;

&lt;p&gt;Imagine you've made some recent changes to your system configuration files in a directory, and you want to identify files that have been modified within the last 10 minutes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;find /path/to/search  &lt;span class="nt"&gt;-mmin&lt;/span&gt; &lt;span class="nt"&gt;-10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will provide you with a list of files in the &lt;code&gt;/etc&lt;/code&gt; directory that have been modified within the last 10 minutes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Locate Recently Changed files
&lt;/h3&gt;

&lt;p&gt;To find files that have been changed within the last 2 days across multiple important directories, use this &lt;code&gt;find&lt;/code&gt; command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;find /usr/bin /usr/sbin &lt;span class="nt"&gt;-ctime&lt;/span&gt; &lt;span class="nt"&gt;-2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By executing this command, you'll obtain a list of files that have undergone changes in the specified time frame.&lt;/p&gt;

&lt;h3&gt;
  
  
  Identify Unused Files in Web Directories
&lt;/h3&gt;

&lt;p&gt;When managing websites, it's important to keep track of files that haven't been accessed for a while. For instance, let's say you want to find files in the &lt;code&gt;/var/www&lt;/code&gt; directory that haven't been accessed for over 300 days. Here's the &lt;code&gt;find&lt;/code&gt; command to achieve that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;find /var/www &lt;span class="nt"&gt;-atime&lt;/span&gt; +300
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Upon executing this command, you'll receive a list of files within the specified directories that meet the time-based criteria.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding files and executing commands
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;find&lt;/code&gt; command is not just about discovering files; it's also about taking action on them. This is where the &lt;code&gt;-exec&lt;/code&gt; flag comes into play. With it, you can execute a command on each file that matches your search criteria.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;find /path/to/search &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"filename"&lt;/span&gt; &lt;span class="nt"&gt;-exec&lt;/span&gt; &lt;span class="nb"&gt;command&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt; &lt;span class="se"&gt;\;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, find text files and print their contents&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;find /home/user/documents &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"*.txt"&lt;/span&gt; &lt;span class="nt"&gt;-exec&lt;/span&gt; &lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt; &lt;span class="se"&gt;\;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Interactively Approve Actions
&lt;/h2&gt;

&lt;p&gt;Sometimes, before making changes to files, you want to be sure. The &lt;code&gt;-ok&lt;/code&gt; flag in &lt;code&gt;find&lt;/code&gt; enables an interactive mode that asks for your confirmation before executing a command on each file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;find /path/to/search &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"filename"&lt;/span&gt; &lt;span class="nt"&gt;-ok&lt;/span&gt; &lt;span class="nb"&gt;command&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt; &lt;span class="se"&gt;\;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example safely deleting files&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;find /home/user/trash_files &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"*~"&lt;/span&gt; &lt;span class="nt"&gt;-ok&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt; &lt;span class="se"&gt;\;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With these scenarios, &lt;code&gt;find&lt;/code&gt; becomes a tool not only for locating files but also for performing actions on them, whether you're printing file contents or confirming deletions. It adds a layer of efficiency and control to your file management tasks&lt;/p&gt;

</description>
      <category>linux</category>
      <category>find</category>
      <category>terminal</category>
    </item>
  </channel>
</rss>
