<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Tech Notes on My Little Blog</title><link>https://www.parkerchenca.com/categories/tech-notes/</link><description>Recent content in Tech Notes on My Little Blog</description><generator>Hugo</generator><language>en-us</language><copyright>Parker Chen</copyright><lastBuildDate>Thu, 10 Sep 2026 11:26:00 +0000</lastBuildDate><atom:link href="https://www.parkerchenca.com/categories/tech-notes/index.xml" rel="self" type="application/rss+xml"/><item><title>Result and Option in short</title><link>https://www.parkerchenca.com/tech/result-and-option-in-short/</link><pubDate>Thu, 10 Sep 2026 11:26:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/result-and-option-in-short/</guid><description>Two old friends in Rust</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
When writing Rust programs, Result and Option are data structures we can hardly avoid. I believe that rather than understanding their underlying mechanisms, we should first quickly figure out how to handle them.</p>
</blockquote>
<h2 id="gift-wrapping">Gift Wrapping</h2>
<p>Actually, we don&rsquo;t need to think of <code>Option&lt;T&gt;</code> and <code>Result&lt;T,E&gt;</code> as too complicated:</p>
<ul>
<li><code>Option</code> contains the data we want, where the data type is <code>T</code>. However, there might be no data inside (<code>None</code>). But regardless, as long as what we care about is wrapped, it <strong>will be</strong> an <code>Option</code>.</li>
<li><code>Result</code> also contains the data we want, but it comes with another &ldquo;restless&rdquo; additional item <code>E</code> (Error). In fact, combinations of Result and Option are very common, such as <code>Result&lt;Option&lt;T&gt;, E&gt;</code>. <code>Result</code> provides a powerful and <strong>unified</strong> specification for Rust&rsquo;s error handling.</li>
</ul>
<h3 id="so-how-do-we-open-the-gift-box">So, how do we open the gift box&hellip;</h3>
<p>The moment of unwrapping gifts is always exciting.</p>
<p>Whether it&rsquo;s <code>Option</code> or <code>Result</code>, we can use <code>unwrap()</code> to open this package.</p>
<ul>
<li>If the gift box contains a normal value, everything goes smoothly, and everyone&rsquo;s happy.</li>
<li>But if it contains something &ldquo;weird&rdquo; (<code>None</code> or <code>Err</code>), the program will immediately <code>panic</code> and crash.</li>
</ul>
<p>Of course, if we insist on using safer unwrapping methods (like <code>unwrap_or</code>, <code>match</code>, etc.), we can control whether the program crashes ourselves, which is very practical.</p>
<h3 id="what-functions-do-these-gift-boxes-provide">What functions do these gift boxes provide?</h3>
<p>Let&rsquo;s quickly go through the methods they provide. Detailed explanations won&rsquo;t be provided here, as I believe you can look up relevant information through <a href="https://doc.rust-lang.org/std/option/">https://doc.rust-lang.org/std/option/</a> and <a href="https://doc.rust-lang.org/std/result/">https://doc.rust-lang.org/std/result/</a>.</p>
<h4 id="option">Option</h4>
<table>
	<thead>
			<tr>
					<th>API</th>
					<th>Purpose</th>
					<th>Return Value and Notes</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><code>is_some()</code></td>
					<td>Check if it&rsquo;s <code>Some</code></td>
					<td><code>bool</code></td>
			</tr>
			<tr>
					<td><code>is_none()</code></td>
					<td>Check if it&rsquo;s <code>None</code></td>
					<td><code>bool</code></td>
			</tr>
			<tr>
					<td><code>unwrap()</code></td>
					<td>Get the value inside <code>Some</code>, panic if <code>None</code></td>
					<td><code>T</code> / <code>panic</code></td>
			</tr>
			<tr>
					<td><code>unwrap_or(default)</code></td>
					<td>Get value, return specified default if <code>None</code></td>
					<td><code>T</code></td>
			</tr>
			<tr>
					<td><code>unwrap_or_else(f)</code></td>
					<td>Get value, call closure <code>f</code> to return default if <code>None</code></td>
					<td><code>T</code></td>
			</tr>
			<tr>
					<td><code>map(f)</code></td>
					<td>If <code>Some</code>, call <code>f</code> on inner value, return new <code>Option</code></td>
					<td><code>Option&lt;U&gt;</code></td>
			</tr>
			<tr>
					<td><code>and_then(f)</code></td>
					<td>If <code>Some</code>, call <code>f</code>, return another <code>Option</code></td>
					<td><code>Option&lt;U&gt;</code></td>
			</tr>
			<tr>
					<td><code>or(other)</code></td>
					<td>If <code>None</code>, return parameter <code>other</code>, otherwise return self</td>
					<td><code>Option&lt;T&gt;</code></td>
			</tr>
			<tr>
					<td><code>or_else(f)</code></td>
					<td>If <code>None</code>, call closure <code>f</code> to return an <code>Option</code></td>
					<td><code>Option&lt;T&gt;</code></td>
			</tr>
			<tr>
					<td><code>as_ref()</code></td>
					<td>Convert <code>Option&lt;T&gt;</code> to immutable reference of inner value <code>Option&lt;&amp;T&gt;</code></td>
					<td><code>Option&lt;&amp;T&gt;</code></td>
			</tr>
			<tr>
					<td><code>as_mut()</code></td>
					<td>Convert <code>Option&lt;T&gt;</code> to mutable reference of inner value <code>Option&lt;&amp;mut T&gt;</code></td>
					<td><code>Option&lt;&amp;mut T&gt;</code></td>
			</tr>
			<tr>
					<td><code>ok_or(err)</code></td>
					<td>Convert <code>Some(value)</code> to <code>Ok(value)</code>, and <code>None</code> to <code>Err(err)</code></td>
					<td><code>Result&lt;T, E&gt;</code></td>
			</tr>
			<tr>
					<td><code>ok_or_else(f)</code></td>
					<td>Same as above, but call closure if <code>None</code></td>
					<td><code>Result&lt;T, E&gt;</code></td>
			</tr>
			<tr>
					<td><code>expect(msg)</code></td>
					<td>Similar to <code>unwrap()</code>, but allows custom error message</td>
					<td><code>T</code> / <code>panic</code></td>
			</tr>
			<tr>
					<td><code>?</code></td>
					<td>Return <code>None</code> directly when <code>None</code> (must be used in functions returning <code>Option</code>)</td>
					<td><code>T</code> / early return</td>
			</tr>
	</tbody>
</table>
<p>Notable methods:</p>
<ul>
<li><code>map(f)</code> provides a way to operate on inner data without unpacking, very commonly used</li>
<li><code>expect(&quot;Hi&quot;)</code> can display error messages when panicking, more practical than <code>unwrap()</code></li>
<li><code>?</code> can greatly improve code cleanliness</li>
<li><code>is_some()</code> and <code>is_none()</code> are also very useful for making decisions</li>
</ul>
<h3 id="result">Result</h3>
<p>Compared to the intuitive and easy-to-understand <code>Option</code>, <code>Result</code> seems more &ldquo;convoluted&rdquo; with an additional type, but essentially it&rsquo;s almost identical to <code>Option</code>: what to do if we didn&rsquo;t get the value (possibly due to an error).</p>
<table>
	<thead>
			<tr>
					<th>API</th>
					<th>Purpose</th>
					<th>Return Value / Notes</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><code>is_ok()</code></td>
					<td>Check if it&rsquo;s <code>Ok</code></td>
					<td><code>bool</code></td>
			</tr>
			<tr>
					<td><code>is_err()</code></td>
					<td>Check if it&rsquo;s <code>Err</code></td>
					<td><code>bool</code></td>
			</tr>
			<tr>
					<td><code>unwrap()</code></td>
					<td>Get value inside <code>Ok</code>, <code>panic</code> if <code>Err</code></td>
					<td><code>T</code> / <code>panic</code></td>
			</tr>
			<tr>
					<td><code>unwrap_or(default)</code></td>
					<td>Get value, return default if <code>Err</code></td>
					<td><code>T</code></td>
			</tr>
			<tr>
					<td><code>unwrap_or_else(f)</code></td>
					<td>Get value, call closure <code>f</code> to return default if <code>Err</code></td>
					<td><code>T</code></td>
			</tr>
			<tr>
					<td><code>map(f)</code></td>
					<td>If <code>Ok</code>, call <code>f</code> on inner value, return new <code>Result</code></td>
					<td><code>Result&lt;U, E&gt;</code></td>
			</tr>
			<tr>
					<td><code>and_then(f)</code></td>
					<td>If <code>Ok</code>, call <code>f</code>, return another <code>Result</code></td>
					<td><code>Result&lt;U, E&gt;</code></td>
			</tr>
			<tr>
					<td><code>map_err(f)</code></td>
					<td>If <code>Err</code>, call <code>f</code> on error, return new <code>Result</code></td>
					<td><code>Result&lt;T, F&gt;</code></td>
			</tr>
			<tr>
					<td><code>or(other)</code></td>
					<td>If <code>Err</code>, return <code>other</code>, otherwise return self</td>
					<td><code>Result&lt;T, E&gt;</code></td>
			</tr>
			<tr>
					<td><code>or_else(f)</code></td>
					<td>If <code>Err</code>, call closure <code>f</code> to return <code>Result</code></td>
					<td><code>Result&lt;T, E&gt;</code></td>
			</tr>
			<tr>
					<td><code>as_ref()</code></td>
					<td>Convert to immutable references</td>
					<td><code>Result&lt;&amp;T, &amp;E&gt;</code></td>
			</tr>
			<tr>
					<td><code>as_mut()</code></td>
					<td>Convert to mutable references</td>
					<td><code>Result&lt;&amp;mut T, &amp;mut E&gt;</code></td>
			</tr>
			<tr>
					<td><code>ok()</code></td>
					<td>Success value → <code>Some(value)</code>, error → <code>None</code></td>
					<td><code>Option&lt;T&gt;</code></td>
			</tr>
			<tr>
					<td><code>err()</code></td>
					<td>Error value → <code>Some(error)</code>, success → <code>None</code></td>
					<td><code>Option&lt;E&gt;</code></td>
			</tr>
			<tr>
					<td><code>expect(msg)</code></td>
					<td>Similar to <code>unwrap()</code>, but allows custom error message</td>
					<td><code>T</code> / <code>panic</code></td>
			</tr>
			<tr>
					<td><code>?</code></td>
					<td>Return early when encountering <code>Err</code> (must be used in functions returning <code>Result</code>)</td>
					<td><code>T</code> / early return</td>
			</tr>
	</tbody>
</table>
<p><code>Result</code> also has: <code>map(f)</code> and <code>?</code>, as well as useful <code>is_ok()</code> and <code>is_err()</code></p>
<p>In <code>Result&lt;T, E&gt;</code>:</p>
<ul>
<li><code>T</code> is the type of value returned on success (e.g., file content, calculation result, etc.).</li>
<li><code>E</code> is the type of value returned on error (e.g., <code>std::io::Error</code>, custom error <code>enum</code>, etc.).</li>
<li>Actually:
<ul>
<li><code>E</code> can be any type, with no restrictions</li>
<li>But to use <code>?</code>, facilitate debugging and printing, <code>E</code> usually needs to implement <code>Debug</code>, <code>Display</code>, <code>Error</code>, and other traits</li>
<li>Yes, <code>E</code> can be very complex types (carrying context, providing helper methods), or very simple error structures (like, a string). <code>Err</code> is just the shell that <code>Result</code> uses to mark &ldquo;this is the error branch&rdquo;, with <code>E</code> inside</li>
</ul>
</li>
</ul>
<h3 id="examples">Examples</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="c1">// ===== Creating Option =====
</span></span></span><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">some_value</span>: <span class="nb">Option</span><span class="o">&lt;</span><span class="kt">i32</span><span class="o">&gt;</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="mi">42</span><span class="p">);</span><span class="w">  </span><span class="c1">// Has value
</span></span></span><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">none_value</span>: <span class="nb">Option</span><span class="o">&lt;</span><span class="kt">i32</span><span class="o">&gt;</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">None</span><span class="p">;</span><span class="w">      </span><span class="c1">// No value
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Common usage: returning from functions
</span></span></span><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">find_number</span><span class="p">(</span><span class="n">flag</span>: <span class="kt">bool</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Option</span><span class="o">&lt;</span><span class="kt">i32</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">if</span><span class="w"> </span><span class="n">flag</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="mi">7</span><span class="p">)</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nb">None</span><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// ===== Creating Result =====
</span></span></span><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">ok_value</span>: <span class="nb">Result</span><span class="o">&lt;</span><span class="kt">i32</span><span class="p">,</span><span class="w"> </span><span class="nb">String</span><span class="o">&gt;</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Ok</span><span class="p">(</span><span class="mi">42</span><span class="p">);</span><span class="w">                    </span><span class="c1">// Success
</span></span></span><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">err_value</span>: <span class="nb">Result</span><span class="o">&lt;</span><span class="kt">i32</span><span class="p">,</span><span class="w"> </span><span class="nb">String</span><span class="o">&gt;</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Err</span><span class="p">(</span><span class="s">&#34;Oops&#34;</span><span class="p">.</span><span class="n">to_string</span><span class="p">());</span><span class="w"> </span><span class="c1">// Failure
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Common usage: returning from functions
</span></span></span><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">divide</span><span class="p">(</span><span class="n">a</span>: <span class="kt">i32</span><span class="p">,</span><span class="w"> </span><span class="n">b</span>: <span class="kt">i32</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Result</span><span class="o">&lt;</span><span class="kt">i32</span><span class="p">,</span><span class="w"> </span><span class="nb">String</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">if</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nb">Err</span><span class="p">(</span><span class="s">&#34;Division by zero&#34;</span><span class="p">.</span><span class="n">to_string</span><span class="p">())</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nb">Ok</span><span class="p">(</span><span class="n">a</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">b</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>]]></content:encoded></item><item><title>Vim in (not so) short</title><link>https://www.parkerchenca.com/tech/vim-in-not-so-short/</link><pubDate>Thu, 10 Sep 2026 11:25:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/vim-in-not-so-short/</guid><description>I want to make it short, but Vim is too powerful</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
Yes, You can always type :h to see help, for example, :h windows</p>
</blockquote>
<h2 id="vim-in-not-so-short"><strong>Vim in not so short</strong></h2>
<h3 id="preliminaries">Preliminaries</h3>
<ul>
<li>When vim is not available, you can temporarily use <code>cat</code> or <code>nano</code> as alternatives</li>
<li>When using a new IDE, you should first learn or configure:
<ul>
<li>save</li>
<li>copy / paste</li>
<li>duplicate line</li>
<li>delete word / delete line</li>
<li>line movement</li>
<li>navigate forward / back</li>
<li>undo / redo</li>
<li>page navigation (page down, page up, center to middle, etc.)</li>
<li>indent / unindent</li>
<li>multi-cursor</li>
<li>search / content search</li>
<li>input commands (<code>Ctrl + P</code> in VSCode, double <code>Shift</code> in IntelliJ, <code>:</code> in vim…)</li>
<li>completion, suggestion, parameter hint, hover hint</li>
<li>go to / peek definition, type, declaration, reference, implementation</li>
<li>rename symbol / refactor (if available)</li>
<li>AI controlling: toggle chat box, trigger inline chat…</li>
<li>tabs / windows management</li>
</ul>
</li>
<li>Use the <code>:help</code> command to query anything you don’t understand</li>
<li><code>:set option?</code> can view current settings</li>
</ul>
<hr>
<h3 id="windows-and-tabs">Windows and Tabs</h3>
<p><strong>Buffer:</strong> Can be understood as a temporary file. Even if this file is edited, it doesn’t mean it’s written to the actual file. We can <strong>observe</strong> buffers through windows and <strong>manage</strong> them through tabs.</p>
<ol>
<li>Use commands starting with <code>b</code> in Ex (command line) mode for buffer operations:
<ul>
<li><code>bd</code> buffer delete; <code>bwipeout</code> clears more thoroughly</li>
<li><code>bn</code> or <code>bnext</code> switch to next buffer</li>
<li><code>bp</code> or <code>bprevious</code> switch to previous buffer</li>
<li><code>ctrl + ^</code>  switch to the last buffer</li>
</ul>
</li>
</ol>
<p><code>Ctrl + W</code> window shortcuts and <code>:sp</code> split commands are the basics of window management. <code>:sp</code> can use parameters to specify files to split (open a new window for this file)</p>
<ol>
<li><code>Ctrl + W</code> + <code>w</code> cycle windows, <code>Ctrl + W</code> + <code>hjkl</code> switch focus left/down/up/right (move cursor)</li>
<li><code>Ctrl + W</code> + <code>=</code> (make window panes equal size)</li>
<li><code>Ctrl + W</code> + <code>+</code> <code>Ctrl + W</code> +  <code>Ctrl + W</code> + <code>&lt;</code> <code>Ctrl + W</code> + <code>&gt;</code> (fine-tune window size)</li>
<li><code>:vsp</code> performs vertical split, dividing into two sides</li>
<li><code>:resize 20</code> sets height to 20 lines; <code>:vertical resize 80</code> sets width to 80 columns</li>
</ol>
<p><code>:tabs</code> is the basic tab management command.</p>
<ol>
<li><code>:tabnew</code> opens a new tab, <code>:tabe</code> (edit) opens a tab for editing. Can be followed by filename.</li>
<li><code>:tabn</code> <code>:tabp</code> switch tabs, or use <code>gt</code> <code>gT</code> to switch</li>
<li>Display current buffer in new tab: <code>:tab split</code></li>
<li><code>:tabmove</code> move tab, for example <code>:tabmove 2</code></li>
<li><strong>Batch execution</strong>:
<ul>
<li><code>:tabdo {cmd}</code> execute on all tabs, e.g., <code>:tabdo set nocursorline</code></li>
<li><code>:windo {cmd}</code> execute on each window in current tab, e.g., <code>:windo diffthis</code></li>
</ul>
</li>
</ol>
<p><code>:only</code> and <code>:close</code> are universal management methods</p>
<ol>
<li>Type <code>:close</code> <code>:only</code> directly to manage windows</li>
<li>Type <code>:tabclose</code> <code>:tabonly</code> to manage tabs</li>
</ol>
<hr>
<h3 id="key-remapping">Key Remapping</h3>
<p>Here’s the key remapping configuration in VSCode vim extension:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"><span class="nt">&#34;vim.leader&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;space&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="nt">&#34;vim.useSystemClipboard&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span> <span class="c1">// important
</span></span></span><span class="line"><span class="cl"><span class="nt">&#34;vim.normalModeKeyBindings&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;before&#34;</span> <span class="p">:</span> <span class="p">[</span><span class="s2">&#34;J&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;after&#34;</span> <span class="p">:</span> <span class="p">[</span><span class="s2">&#34;5&#34;</span><span class="p">,</span> <span class="s2">&#34;j&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;before&#34;</span> <span class="p">:</span> <span class="p">[</span><span class="s2">&#34;K&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;after&#34;</span> <span class="p">:</span> <span class="p">[</span><span class="s2">&#34;5&#34;</span><span class="p">,</span> <span class="s2">&#34;k&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">],</span>
</span></span><span class="line"><span class="cl"><span class="nt">&#34;vim.normalModeKeyBindingsNonRecursive&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;before&#34;</span> <span class="p">:</span> <span class="p">[</span><span class="s2">&#34;&lt;Backspace&gt;&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;after&#34;</span> <span class="p">:</span> <span class="p">[</span><span class="s2">&#34;x&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">],</span>
</span></span><span class="line"><span class="cl"><span class="nt">&#34;vim.insertModeKeyBindingsNonRecursive&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="p">],</span>
</span></span><span class="line"><span class="cl"><span class="nt">&#34;vim.visualModeKeyBindingsNonRecursive&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;before&#34;</span> <span class="p">:</span> <span class="p">[</span><span class="s2">&#34;&lt;Backspace&gt;&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;after&#34;</span> <span class="p">:</span> <span class="p">[</span><span class="s2">&#34;d&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Common key aliases:</p>
<ul>
<li><code>&lt;Backspace&gt;</code></li>
<li><code>&lt;C-c&gt;</code> -&gt; Ctrl + C</li>
<li><code>&lt;A-c&gt;</code> -&gt; Alt + C</li>
<li><code>&lt;Shift&gt;</code></li>
<li><code>&lt;CapsLock&gt;</code></li>
<li><code>&lt;Tab&gt;</code></li>
<li><code>&lt;Enter&gt;</code></li>
<li><code>&lt;Esc&gt;</code></li>
<li><code>&lt;Cmd-&gt;</code> Mac specific</li>
<li><code>&lt;Up&gt;</code></li>
<li><code>&lt;Down&gt;</code></li>
<li><code>&lt;Left&gt;</code></li>
<li><code>&lt;Right&gt;</code></li>
</ul>
<hr>
<h4 id="vim-configuration-file">vim Configuration File</h4>
<p>Use the <code>.vimrc</code> file in the <code>home</code> directory:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-mysql" data-lang="mysql"><span class="line"><span class="cl"><span class="s2">&#34; This is vimscript, so use let for assignment and &#34;</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">comments</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">nnoremap</span><span class="w"> </span><span class="o">&lt;</span><span class="n">SPACE</span><span class="o">&gt;</span><span class="w"> </span><span class="o">&lt;</span><span class="n">Nop</span><span class="o">&gt;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">let</span><span class="w"> </span><span class="n">mapleader</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">&#34; &#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kt">set</span><span class="w"> </span><span class="n">number</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34; Use system clipboard
</span></span></span><span class="line"><span class="cl"><span class="s2">set clipboard=unnamedplus
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34;</span><span class="w"> </span><span class="n">Map</span><span class="w"> </span><span class="o">`</span><span class="n">J</span><span class="o">`</span><span class="w"> </span><span class="k">to</span><span class="w"> </span><span class="o">`</span><span class="mi">5</span><span class="n">j</span><span class="o">`</span><span class="p">,</span><span class="w"> </span><span class="o">`</span><span class="n">K</span><span class="o">`</span><span class="w"> </span><span class="k">to</span><span class="w"> </span><span class="o">`</span><span class="mi">5</span><span class="n">k</span><span class="o">`</span><span class="p">,</span><span class="w"> </span><span class="o">`&lt;</span><span class="n">Backspace</span><span class="o">&gt;`</span><span class="w"> </span><span class="k">to</span><span class="w"> </span><span class="o">`</span><span class="n">x</span><span class="o">`</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">nnoremap</span><span class="w"> </span><span class="n">J</span><span class="w"> </span><span class="mi">5</span><span class="n">j</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">nnoremap</span><span class="w"> </span><span class="n">K</span><span class="w"> </span><span class="mi">5</span><span class="n">k</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">nnoremap</span><span class="w"> </span><span class="o">&lt;</span><span class="n">Backspace</span><span class="o">&gt;</span><span class="w"> </span><span class="n">x</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34; inoremap
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34;</span><span class="w"> </span><span class="n">vnoremap</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34; nmap
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34;</span><span class="w"> </span><span class="n">imap</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="s2">&#34; vmap
</span></span></span><span class="line"><span class="cl"><span class="s2">nnoremap &lt;Enter&gt; o&lt;Esc&gt;
</span></span></span></code></pre></div><hr>
<h3 id="unbound-keys">Unbound Keys</h3>
<p>In VSCode and other IDEs, you can return Vim-controlled keys to the IDE, since they have no use in GUI interfaces.</p>
<ul>
<li><code>Ctrl + D</code> scroll down</li>
<li><code>Ctrl + Z</code> suspend Vim</li>
<li><code>Ctrl + X</code> decrease number at cursor by 1, in insert mode it’s completion, decrease by 1 is quite useful</li>
<li><code>Ctrl + C</code> can be considered</li>
<li><code>Ctrl + F</code> scroll forward, in insert mode used to view command history</li>
<li><code>Ctrl + W</code> window command, delete one word before cursor</li>
<li><code>Ctrl + P</code> completion</li>
<li><code>Ctrl + S</code> pause output</li>
<li><code>Ctrl + Q</code> same as <code>Ctrl + V</code>, only <code>q</code> alone is for recording macros, VSCode defaults to <em>Add cursor below</em>, multi-cursor editing tool</li>
<li><code>Ctrl + Y / E</code> scroll window up/down by 1 line</li>
<li><code>Ctrl + T</code> depends on situation</li>
</ul>
<hr>
<h3 id="quick-reference">Quick Reference</h3>
<p><strong>(jut for memory, may not be accurate)</strong></p>
<ol>
<li><code>w</code> -&gt; word</li>
<li><code>b</code> -&gt; back</li>
<li><code>e</code> -&gt; end</li>
<li><code>H</code> -&gt; page head; <code>L</code> -&gt; low; <code>M</code> -&gt; middle</li>
<li><code>zz</code> move current line to the middle position</li>
<li><code>Ctrl + U</code> &amp; <code>Ctrl + D</code> half screen move up &amp; down
<ul>
<li><code>Ctrl + F</code> &amp; <code>Ctrl + B</code> full screen move forward &amp; back</li>
</ul>
</li>
<li><code>g</code> -&gt; go (sometimes obviously more than that)
<ul>
<li><code>gn</code> <strong>go to next (matched)</strong>, <strong>commonly used</strong></li>
<li><code>gi</code> go to (last) insert</li>
<li><code>gd</code> go to definition</li>
<li><code>gf</code> go to file</li>
</ul>
</li>
<li><code>d</code> -&gt; delete (actually puts deleted content into register); sometimes means down
<ul>
<li><code>dd</code> delete one line</li>
</ul>
</li>
<li><code>x</code> -&gt; <code>dl</code>; <code>X</code> -&gt; <code>dh</code>
<ul>
<li><code>s</code> -&gt; (<code>x</code> + <code>i</code>)</li>
<li><code>c</code> -&gt; change (<code>d</code> + <code>i</code>)</li>
</ul>
</li>
<li><code>y</code> -&gt; yank</li>
<li><code>p</code> -&gt; do paste | as paragraph</li>
<li><code>{</code> <code>}</code> -&gt; paragraph</li>
<li><code>f</code> -&gt; find occurrence (<strong>char</strong>)
<ul>
<li><code>;</code> -&gt; next occurrence</li>
<li><code>,</code> -&gt; last occurrence</li>
<li><code>t</code> -&gt; till next occurrence</li>
<li><code>F</code> -&gt; backward to occurrence</li>
</ul>
</li>
<li><code>/</code> -&gt; search item with pattern
<ul>
<li><code>n</code> -&gt; next item</li>
<li><code>?</code> -&gt; back search</li>
</ul>
</li>
<li><code>u</code> -&gt; undo; <code>Ctrl + R</code> redo</li>
<li><code>123…</code> -&gt; as line number / do multiple times</li>
<li><code>i</code> -&gt; do insert | as inner (inside); <code>o</code> -&gt; open a line below; <code>a</code> -&gt; append | around</li>
<li><code>s</code> -&gt; as sentence | do substitute</li>
<li><code>q</code> -&gt; record macro</li>
<li><code>v</code> -&gt; visual</li>
<li><code>s</code> -&gt; surrounding. <code>cs{old}{new}</code>. plugin command
<ul>
<li><code>v</code> <code>S{desire pair}</code> -&gt; surrounding by.</li>
</ul>
</li>
<li><code>J</code> join</li>
<li><code>r</code> replace</li>
</ol>
<hr>
<h4 id="special-characters">Special Characters</h4>
<ol>
<li><code>@</code> -&gt; execute register content</li>
<li><code>.</code> <strong>&gt; as current line | do repeat last change</strong>, <strong>very commonly used</strong>, for repeating <strong>edit</strong> operations</li>
<li><code>%</code> -&gt; as all lines(all contents); in normal mode represents matching symbols like <code>{[(</code></li>
<li><code>0</code> -&gt; beginning of line
<ul>
<li><code>$</code> -&gt; end of line</li>
<li><code>^</code> first meaningful character</li>
<li><code>_</code> first meaningful character (can be operated by <code>g</code> etc.)</li>
<li><code>g_</code> last meaningful character</li>
</ul>
</li>
<li><code>;</code> <strong>repeat</strong> last <code>f, F, t, T</code> command. For example, if you used <code>f</code> to find a <strong>character</strong>, pressing <code>;</code> will continue to find the next matching character.
<ul>
<li><code>,</code> reverse repeat</li>
</ul>
</li>
<li><code>'</code> for mark navigation. For example, pressing <code>'a</code> jumps to the beginning of line of mark ‘a’.</li>
<li>``` (backtick) for mark navigation. For example, pressing ``a` jumps to the exact position of mark ‘a’.</li>
<li><code>~</code> change char case.</li>
<li><code>&amp;</code> repeat last substitution command</li>
</ol>
<hr>
<h4 id="modes">Modes</h4>
<ol>
<li>Normal mode: Enter normal mode when first starting, press <code>i</code> (insert) to enter insert mode, press <code>:</code> to enter command input mode</li>
<li>Insert mode: Edit file, press Esc to exit.</li>
<li>Command input mode: Input commands, press Esc to exit.</li>
<li>Press <code>v</code> to enter visual mode, generally used for selecting paragraphs</li>
</ol>
<h4 id="command-structure">Command Structure</h4>
<ol>
<li>Normal mode commands are almost based on the <code>verb</code> + <code>adj(count)</code> + <code>obj(motion, text-object)</code> pattern, e.g.: <code>d3j</code>, <code>ca(</code>
<ul>
<li>Omitting <code>verb</code> means <strong>cursor movement</strong>, which can actually be understood as a type of <code>verb</code>.
<ul>
<li>Example: <code>3j</code>, move down 3 lines</li>
<li>Example: <code>0</code>, <code>$</code>, these are special characters</li>
<li>Example: <code>v3w</code>, <code>v</code> only switches mode, doesn’t count as <code>verb</code>, but subsequent behavior without <code>verb</code> is treated as cursor movement</li>
</ul>
</li>
<li><strong>Special case</strong>: Omitting <code>adj.</code> means based on current position, or only operating on <strong>one object</strong>.
<ul>
<li>Example: <code>cw</code>, <code>f{</code></li>
</ul>
</li>
<li><strong>Special case</strong>: Omitting both <code>adj.</code> and <code>obj.</code> generally means some single character/line shortcuts
<ul>
<li>Example: <code>dd</code>, <code>yy</code>, <code>gg</code></li>
<li>Example: <code>s</code>, <code>x</code>, <code>~</code>, <code>u</code></li>
</ul>
</li>
</ul>
</li>
<li>Command line mode has almost no pattern. If anything, they can almost all be categorized as command-like modes.
<ul>
<li>verb + obj pattern: <code>:set number</code>, <code>:r file</code> (read file)</li>
<li>adj + verb pattern: <code>:3,5 d</code>
<ul>
<li>adj + verb + obj: <code>:3,5 d0</code></li>
</ul>
</li>
<li>obj pattern: <code>:map</code></li>
<li>verb pattern: <code>:w</code>, <code>:q</code></li>
<li>Special pattern (can be viewed as mode switching): <code>:!command</code> (execute external command)</li>
<li>Command-like pattern: <code>:s/foo/bar/gc</code></li>
</ul>
</li>
</ol>
<h4 id="repeat-operations">Repeat Operations</h4>
<ul>
<li><code>.</code> for <strong>modifications</strong>.</li>
<li><code>;</code> for f, etc.</li>
<li><code>r</code> means replace</li>
<li><code>f</code> <code>sth</code> -&gt; <code>r</code> -&gt; <code>;</code> -&gt; <code>.</code> -&gt; <code>;</code> -&gt; <code>.</code> -&gt; … : guess what will happen?</li>
<li><code>gn</code> for <code>/</code> etc. Need to operate on current search content once first, then use <code>.</code> to repeat.</li>
</ul>
<h4 id="tips">Tips</h4>
<ul>
<li><code>verb</code> is almost never absent, omitting <code>verb</code> generally means <strong>movement</strong> (<code>v</code> provides selection function, but still needs to <strong>move</strong> to <strong>some position</strong> to trigger)</li>
<li>At the same time, <code>obj</code> is also almost never absent, omitting <code>obj</code> generally means <strong>current position</strong></li>
</ul>
<p>When inputting commands, if you’re unclear what else to input, consider these questions:</p>
<ol>
<li>
<p>Does the command have an object? E.g., <code>w, p, s</code>.
(Specifically, line operations generally omit objects).
Selection in <code>v</code> mode actually provides objects. Similarly, <strong>movement actions actually also provide objects.</strong>
So, this part should be <strong>considered first, but input last</strong>.</p>
</li>
<li>
<p>Does the command have modifiers?
If there’s a <strong>clear area to operate on</strong>, you must pay attention to modifier input.
Because if not provided, it will <strong>immediately</strong> operate based on current position, very easy to cause misoperations.</p>
</li>
<li>
<p>What does the command need to do?
Please treat this as the last part to think about, to control vim behavior more precisely.
But when inputting commands, generally need to input first.
So, <strong>input this first.</strong></p>
</li>
</ol>
<p><strong>Seqs: 3 → 2 → 1</strong></p>
<hr>
<h3 id="commonly-used-commands">Commonly used Commands</h3>
<ul>
<li><code>:w</code> save</li>
<li><code>:q</code> quit</li>
<li><code>:q!</code> force quit without saving</li>
<li><code>:w filename</code> save file as filename</li>
<li><code>:w! filename</code> force save to filename</li>
<li><code>:set nu</code> <code>:set number</code> display line numbers, <strong>commonly used</strong></li>
<li><code>/word</code> search downward (note, no <code>:</code>, when pressing <code>/</code>, command line becomes <code>/</code> mode)
<ul>
<li>Press <code>n, N</code> to search next/previous</li>
<li><code>?word</code> search upward</li>
</ul>
</li>
<li><code>u</code> and <code>:u</code> undo</li>
<li><code>Ctrl + R</code> redo</li>
<li><code>x</code> = <code>dl</code>, <code>X</code> = <code>dh</code></li>
<li><code>s</code> = <code>ch</code></li>
</ul>
<h4 id="compound-commands">Compound Commands</h4>
<ul>
<li><code>:5 d</code> delete line 5, <strong>commonly used</strong></li>
<li><code>:3,5 d</code> delete <strong>lines 3 to 5</strong></li>
<li><code>:$ d</code> delete last line of document</li>
<li><code>:% d</code> delete all content in document</li>
<li><code>:n move m</code> move line n to after line m, <strong>commonly used</strong></li>
<li><code>:n,n+3 t m</code> copy <strong>lines n to n+3</strong> to <strong>after</strong> line m, <strong>commonly used</strong>
<ul>
<li>Summary: <code>:n,m</code> generally means from line n to line m</li>
</ul>
</li>
<li><code>:%s/hello/nihao/g</code> replace all hello with nihao, similar to <code>sed</code> operation
<ul>
<li><code>:s/hello/nihao/g</code> only replace in current line</li>
</ul>
</li>
<li><code>:5,8s/hello/nihao/g</code> replace hello with nihao in lines 5-8</li>
</ul>
<h3 id="common-shortcuts">Common Shortcuts</h3>
<h4 id="movement">Movement</h4>
<ol>
<li><code>Ctrl + O</code> previous position, <code>Ctrl + I</code> next position</li>
<li>If you have <code>Home</code> <code>End</code> <code>PageUp</code> and <code>PageDown</code> keys, you can use them directly, adding <code>Ctrl</code> is more convenient
<ol>
<li><code>PgUp</code> <code>PgDown</code> behavior varies, specifically use with <code>Ctrl</code> and <code>Shift</code></li>
</ol>
</li>
<li><code>Ctrl + U</code> and <code>Ctrl + D</code> half screen scroll; <code>Ctrl + F</code> and <code>Ctrl + B</code> full screen scroll</li>
<li><code>Ctrl + Up</code> to beginning of line, vice versa</li>
</ol>
<hr>
<h3 id="normal-mode">Normal Mode</h3>
<h4 id="cursor-movement"><strong>Cursor Movement</strong></h4>
<h4 id="character-based-movement">Character-based Movement</h4>
<ul>
<li><code>h</code> <code>l</code> move left/right, <code>k</code> <code>j</code> move up/down, arrow keys also work</li>
<li>Use <code>f</code> to find next <strong>character</strong>, uppercase for reverse search; using <code>t</code> stops before that character
<ul>
<li>Use <code>;</code> and <code>,</code> to repeat forward/backward search</li>
</ul>
</li>
<li><code>^</code> move to first non-whitespace position</li>
<li><code>g_</code> find first non-whitespace position from end of line</li>
<li>Use <code>$</code> to move to end of line</li>
<li>Use <code>%</code> to match brackets like <code>( { [</code></li>
</ul>
<h4 id="word-based-movement">Word-based Movement</h4>
<ul>
<li><code>w</code> move to next word, <strong>commonly used</strong>, remember as word</li>
<li><code>b</code> move to beginning of current/previous word, <strong>commonly used</strong>, remember as back</li>
<li><code>e</code> move to end of current/next word, <strong>commonly used</strong>, remember as end
<ul>
<li>Uppercase <code>W, B, E, gE</code> for including characters after words</li>
<li><code>ge</code> move to end of previous word</li>
<li><code>3w</code> can move 3 times</li>
</ul>
</li>
<li>Use <code>/</code> and <code>?</code> to search for <code>pattern</code>, use <code>n</code> and <code>N</code> to jump to next/previous</li>
</ul>
<h4 id="line-based-movement">Line-based Movement</h4>
<ul>
<li><code>g</code> is the most basic line movement command</li>
<li><code>0</code> move cursor to beginning of line, <code>$</code> move cursor to end of line</li>
<li><code>Home</code> key to beginning of line, <code>End</code> key to end of line</li>
<li><code>G</code> (Shift+G)/<code>gg</code> move cursor to end/beginning of file</li>
<li>Actually <code>G</code> is go, so you can input <code>500G</code> or <code>500gg</code> to locate to line <code>500</code>, <strong>commonly used</strong>
<ul>
<li>Or directly use <code>:line_number</code> to locate</li>
<li><code>gi</code> return to last insert location, <strong>commonly used</strong></li>
</ul>
</li>
</ul>
<h4 id="block-or-screen-based-movement">Block or Screen-based Movement</h4>
<ul>
<li><code>{</code> <code>}</code> move by paragraph</li>
<li><code>H</code> move to <strong>top line of screen</strong>; <code>L</code> move to <strong>bottom line of screen</strong>; <code>M</code> move to <strong>middle of screen</strong></li>
</ul>
<h4 id="mark-based-movement">Mark-based Movement</h4>
<ul>
<li><code>ma</code> set mark a</li>
<li><code>'a</code> jump to beginning of line of mark a</li>
<li>``a` jump to exact position of mark a</li>
<li><code>''</code> jump to beginning of line of previous position, <strong>commonly used</strong></li>
<li>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"></code></pre></div></li>
</ul>
<hr>
<h4 id="operation-commands">Operation Commands</h4>
<p>Follow <code>{operator}{count}{motion}</code> pattern, e.g.: <code>d2w</code></p>
<ul>
<li><code>c</code> change, <code>d</code> delete, <code>y</code> yank (copy), <code>p</code> paste
<ul>
<li>change means delete corresponding content and directly enter insert mode</li>
</ul>
</li>
<li><code>gu</code> <code>gU</code> or directly press <code>~</code> to change char’s case (<strong>commonly used</strong>)</li>
<li><code>=</code> format, for formatting, need to set code standards in advance, e.g.:</li>
</ul>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">set autoindent        &#34; Inherit indentation from previous line
</span></span><span class="line"><span class="cl">set smartindent       &#34; Smart indentation based on syntax
</span></span><span class="line"><span class="cl">set cindent           &#34; C/C++ style indentation
</span></span><span class="line"><span class="cl">set shiftwidth=4      &#34; Move 4 spaces for each indentation operation
</span></span><span class="line"><span class="cl">set tabstop=4         &#34; Display one Tab as 4 spaces
</span></span><span class="line"><span class="cl">set expandtab         &#34; Use spaces instead of Tab
</span></span></code></pre></div><p>Common formatting commands:</p>
<ul>
<li>
<p><code>==</code>: Format current line.</p>
</li>
<li>
<p><code>=motion</code>: Format range specified by <code>motion</code>.</p>
</li>
<li>
<p><code>=ap</code>: Format current paragraph (<code>ap</code> means “a paragraph”).</p>
</li>
<li>
<p><code>=%</code>: Format content within brackets matching current cursor position.</p>
</li>
<li>
<p><code>gg=G</code>: Format entire file.</p>
</li>
<li>
<p>Use <code>&gt;&gt;</code> for indentation, use <code>&gt;</code> when target is provided</p>
</li>
</ul>
<h4 id="text-objects-delete-content-of-specific-patterns">Text Objects (delete content of specific patterns)</h4>
<p>Follow <code>{operator}{a/i}{text object}</code> pattern, e.g.: <code>di'</code> (delete inside ’)</p>
<ul>
<li>Generally used with <code>c</code>, <code>d</code></li>
<li>a -&gt; around, i -&gt; inside</li>
<li>text-object identifiers:
<ul>
<li><code>w</code> word</li>
<li><code>s</code> sentence</li>
<li><code>p</code> paragraph</li>
<li><code>'&quot;[{&lt;</code> ` corresponding to respective special blocks</li>
<li><code>t</code> tag, commonly used in html language, between <code>&gt;&lt;</code></li>
</ul>
</li>
</ul>
<h4 id="copy-and-delete">Copy and Delete</h4>
<ul>
<li><code>yy</code> copy current line, <strong>commonly used</strong></li>
<li><code>dd</code> cut current line, <strong>commonly used</strong></li>
<li><code>3dd</code> delete 3 lines, <strong>commonly used</strong></li>
<li><code>p</code>/<code>P</code> paste content after/before cursor, <strong>commonly used</strong></li>
<li><code>x</code> delete character at cursor, <code>X</code> delete previous character</li>
<li><code>r</code> modify character at cursor</li>
<li><code>R</code> enter replace mode</li>
</ul>
<h4 id="undo">Undo</h4>
<ul>
<li><code>u</code> undo, <strong>commonly used</strong></li>
<li><code>Ctrl + R</code> redo, <strong>commonly used</strong></li>
</ul>
<h4 id="enter-insert-mode">Enter Insert Mode</h4>
<ul>
<li><code>i</code> enter insert mode at current position</li>
<li><code>a</code> enter insert mode at next character</li>
<li><code>A</code> enter insert mode at end of line</li>
<li><strong><code>o</code> enter insert mode on next line</strong>, often used with <code>G</code> and <code>End</code>, <strong>commonly used</strong></li>
<li><code>s</code> delete current character and enter insert mode</li>
<li><code>S</code> delete current line and enter insert mode</li>
<li><code>cw</code> delete next word and enter insert mode</li>
<li><code>cb</code> delete previous word and enter insert mode</li>
</ul>
<hr>
<h3 id="insert-mode">Insert Mode</h3>
<p>Generally use shortcuts for operations</p>
<h4 id="cursor-movement-1">Cursor Movement</h4>
<ol>
<li><code>Ctrl + A</code> move cursor to beginning of line, uppercase moves to beginning of document</li>
<li><code>Ctrl + E</code> move cursor to end of line</li>
</ol>
<h4 id="text-operations">Text Operations</h4>
<ol>
<li><code>Ctrl + W</code>: Delete one word before cursor.</li>
<li><code>Ctrl + U</code>: Delete all content from current cursor position to beginning of line.</li>
<li><code>Ctrl + T</code> increase indentation to the right</li>
<li><code>Ctrl + D</code> decrease indentation to the left</li>
<li><code>Ctrl + R</code>: Insert register content. After pressing, need to input register identifier, e.g., <code>Ctrl + R, 0</code> inserts content of register 0.</li>
</ol>
<h4 id="completion-features">Completion Features</h4>
<ol>
<li><code>Ctrl + N</code>: Auto-complete next matching word. <strong>commonly used</strong></li>
<li><code>Ctrl + P</code>: Auto-complete previous matching word.</li>
<li><code>Ctrl + X</code>, <code>Ctrl + L</code>: Full line completion, shows dropdown menu</li>
<li><code>Ctrl + X</code>, <code>Ctrl + N/P</code>: Word completion based on current file.</li>
<li><code>Ctrl + X</code>, <code>Ctrl + F</code>: Filename completion.</li>
<li><code>Ctrl + X</code>, <code>Ctrl + K</code>: Dictionary lookup completion.</li>
</ol>
<h4 id="others">Others</h4>
<ol>
<li><code>Ctrl + C</code>: Exit input mode. Replace Esc, <strong>commonly used</strong></li>
<li><code>Ctrl + O</code>: Temporarily switch to normal mode to execute one command, then return to input mode. <strong>commonly used</strong></li>
<li>What if you press wrong key? In normal mode use <code>Ctrl + O</code> to return to previous position, meaning in input mode press <code>Ctrl + O</code> x2</li>
</ol>
<hr>
<h3 id="visual-mode">Visual Mode</h3>
<p>Follow <code>{trigger v}{motion}{operator}</code> pattern, e.g.: <code>v2wd</code> (select two words then delete)</p>
<ul>
<li>Press <code>v</code> for character selection, <code>V</code> for line selection, <code>Ctrl + V</code> for block selection</li>
<li>Generally only used for copy-paste, operation speed is slow</li>
</ul>
<hr>
<h3 id="-command-mode"><code>:</code> Command Mode</h3>
<h4 id="batch-processing-delete-move-copy-paste">Batch Processing (delete, move, copy, paste)</h4>
<ol>
<li><code>:2,5d a</code>: Delete <strong>lines 2 to 5</strong> and <strong>save in register a</strong></li>
<li><code>0</code> line 0; `# Vim in a Nutshell</li>
<li><code>:.,+3d</code> delete current lint &amp; plus 3 lines</li>
<li>In <code>visual</code> mode，<code>:'&lt;,'&gt;d</code> means “delete selected content”</li>
<li><code>@:</code> repeat last <code>:</code> command
<ul>
<li>After using <code>q</code> for macro recording we can use <code>@@</code> repeat it</li>
<li>After <code>@:</code> , <code>@@</code> is still available</li>
</ul>
</li>
<li><code>:'&lt;,'&gt;move .</code>
<ul>
<li><code>:m 10</code> move (current line) to 10 line after</li>
</ul>
</li>
<li><code>:/</code> looking for last found pattern</li>
</ol>
<hr>
<h4 id="quick-reference-1">Quick Reference</h4>
<h4 id="find-and-replace">Find and Replace</h4>
<ul>
<li><strong><code>:%s/old/new/g</code></strong>: In entire file range, replace all strings matching <code>old</code> with <code>new</code>. Add <code>c</code> to ask before each replacement.</li>
<li><strong><code>:s/old/new/g</code></strong>: Replace all <code>old</code> with <code>new</code> in current line.</li>
<li><strong><code>:g/pattern/d</code></strong>: Delete all lines matching <code>pattern</code>.</li>
<li><strong><code>:'&lt;,'&gt;s/old/new/g</code></strong>: In visual mode selected range, replace all <code>old</code> with <code>new</code>.</li>
<li><strong><code>:'&lt;,'&gt;normal command</code></strong>: Execute <code>normal</code> mode command on each line selected in visual mode.</li>
</ul>
<h4 id="line-operations">Line Operations</h4>
<ul>
<li><strong><code>:d</code></strong>: Delete current line (similar to <code>dd</code>).</li>
<li><strong><code>:t .+1</code></strong>: Copy current line and paste to next line.</li>
<li><strong><code>:m .+1</code></strong>: Move current line down one line.</li>
<li><strong><code>:m .-2</code></strong>: Move current line up two lines.</li>
<li><code>:-3,. m .+1</code>: Move 3 lines above current line to below current line</li>
<li><code>:-3,.y | :.+1put</code>: Copy above three lines, paste to next line. <code>put</code> creates new line, <code>p</code> pastes at cursor position</li>
</ul>
<h4 id="sed-like-command-usage">sed-like Command Usage</h4>
<ol>
<li>Replace all matching patterns at once: <code>:%s/pattern/replacement/gc</code> for entire file range (<code>%</code>), substitute (<code>s</code>) <code>pattern</code> with <code>replacement</code></li>
<li><code>gc</code> are <code>flags</code>, common <code>flags</code> include:
<ul>
<li><code>g</code>: Global replacement (apply command to all lines)</li>
<li><code>c</code>: Ask before each command execution.</li>
<li><code>i</code>: Ignore case</li>
<li><code>n</code>: Maximum number of replacements</li>
<li><code>p</code>: Print results</li>
<li><code>v</code>: Invert results</li>
<li><code>!</code>: Pass to external tool -&gt; <code>%!sort</code> will sort entire text</li>
</ul>
</li>
<li><strong>Explicitly</strong> use <strong>normal commands</strong> in <code>Ex</code> mode. Use <code>norm</code>
<ul>
<li>Very useful with v mode</li>
<li>Example: <code>:'&lt;,'&gt;norm A!</code>, will <strong>for content selected in v mode (‘&lt;,’&gt;)</strong>, uniformly <strong>add a “!” at the end of lines (A)</strong></li>
</ul>
</li>
</ol>
<p><code>%</code> itself is shorthand for **`1,# Vim in a Nutshell</p>
<hr>
<h3 id="tips-1">Tips</h3>
<ul>
<li>Accidentally pressed <code>Ctrl + S</code>? Use <code>Ctrl + Q</code> to release</li>
<li>It’s best not to use the right numeric keypad for editing, there might be key conflicts</li>
</ul>
<hr>
<h3 id="copy-paste-issues">Copy-Paste Issues</h3>
<p>Vim editor has its own clipboard system called registers. Vim uses registers to store text, which are different from X11 clipboards. If Vim is compiled with X11 clipboard support (through +clipboard option), then you can use special registers <code>&quot;*</code> and <code>&quot;+</code> to access X11’s PRIMARY and CLIPBOARD.</p>
<h4 id="paste-mode">Paste Mode</h4>
<p>To prevent auto-formatting from corrupting pasted content, Vim provides paste mode. Before pasting, execute <code>:set paste</code> command to enter paste mode, which will temporarily disable auto-indent, auto-wrap and other functions. After pasting, execute <code>:set nopaste</code> to return to normal mode.</p>
<p>You can also install some programs to access X11 clipboard, such as <strong>xclip</strong> or <strong>xsel</strong>.</p>
<p>Right mouse button enters visual mode?</p>
<ul>
<li><code>:set mouse-=a</code></li>
</ul>
<hr>
<h4 id="register-overview">Register Overview</h4>
<p>Vim uses a set of registers as its “clipboard”. These registers can be used to save text and paste later. Each register has an identifier, which can be a single letter or special character. Here are some basics about Vim registers:</p>
<p>Note, to use registers, first press <code>&quot;</code>, then <strong>switch</strong> to the desired register, then perform operations</p>
<p>To view register status, type <code>:reg</code> in command line mode</p>
<hr>
<h4 id="basic-registers">Basic Registers</h4>
<ul>
<li><code>&quot;&quot;</code> - Default register, if you don’t know where copied content went, look here</li>
<li><code>&quot;0</code> - Number 0 register. Stores content of your last yank (copy).</li>
<li><code>&quot;-</code> - Small delete register. Stores content of your last delete or change that’s less than one line.</li>
<li><code>&quot;1</code> to <code>&quot;9</code> - Number registers. Store your recent delete or change history (<code>&quot;1</code> is most recent, <code>&quot;9</code> is oldest).</li>
<li><code>&quot;a</code> to <code>&quot;z</code> or <code>&quot;A</code> to <code>&quot;Z</code> - Named registers. You can use lowercase letters to store text, uppercase letters to append text to corresponding lowercase register.</li>
</ul>
<hr>
<h4 id="special-registers">Special Registers</h4>
<ul>
<li><code>&quot;*</code> and <code>&quot;+</code> - Clipboard registers. In Vim with clipboard support (usually GUI version Vim or Vim with <code>+clipboard</code> feature), these two registers communicate with system clipboard:
<ul>
<li><code>&quot;*</code> register corresponds to X11’s <code>PRIMARY</code> clipboard (usually the select-to-copy one).</li>
<li><code>&quot;+</code> register corresponds to <code>CLIPBOARD</code> clipboard (usually used with <code>Ctrl+C</code>/<code>Ctrl+V</code> key combinations). <strong>Most commonly used.</strong></li>
</ul>
</li>
</ul>
<hr>
<h4 id="using-registers">Using Registers</h4>
<ul>
<li><strong>Copy to register</strong>: You can use <code>&quot;ay</code> to copy to register <code>a</code>, where <code>a</code> is the register name, <code>y</code> is the yank command.
<ul>
<li>Almost the same in visual mode</li>
</ul>
</li>
<li><strong>Paste from register</strong>: To paste from register, you can use <code>&quot;ap</code> to paste content of register <code>a</code>, where <code>a</code> is the register name, <code>p</code> is the paste command.</li>
<li><strong>In insert mode</strong>: Use <code>Ctrl + R</code> to call up <code>&quot;</code> symbol</li>
</ul>
<h4 id="using-registers-in-insert-mode">Using Registers in Insert Mode</h4>
<p>Press</p>
<p><code>Ctrl + R + register name</code></p>
<p>For example</p>
<p><code>Ctrl + R + &quot;</code> uses default register, <code>Ctrl + R + +</code> uses system register.</p>
<hr>
<h4 id="using-registers-in-terminal">Using Registers in Terminal</h4>
<p>When you use Vim in terminal instead of GUI version, accessing system clipboard becomes more complex, because Vim needs to include clipboard support at compile time. You can run <code>vim --version</code> to see if your Vim supports clipboard (look for <code>+clipboard</code> or <code>+xterm_clipboard</code>).</p>
<p>If your Vim supports clipboard, you can interact with system clipboard in the following ways:</p>
<ul>
<li>Use <code>&quot;*y</code> to copy to system’s PRIMARY clipboard.</li>
<li>Use <code>&quot;+y</code> to copy to system’s CLIPBOARD clipboard.</li>
<li>Use <code>&quot;*p</code> or <code>&quot;+p</code> to paste from corresponding system clipboard to Vim.</li>
</ul>
<p>If your Vim doesn’t have clipboard support, you won’t be able to directly access system clipboard from Vim. In this case, you need to use external programs (like <code>xclip</code> or <code>xsel</code>) to help you copy Vim register content to system clipboard, or paste from system clipboard to Vim.</p>
<hr>
<h3 id="external-commands">External Commands</h3>
<h4 id="using--to-execute-external-commands">Using <code>:!</code> to Execute External Commands</h4>
<p>You can use <code>:!</code> followed by command to execute any external command. For example, if you want to see current directory contents, you can type in Vim’s command mode:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">:!ls
</span></span></code></pre></div><h4 id="using-r-to-read-external-command-output">Using <code>:r</code> to Read External Command Output</h4>
<p>If you want to insert output of <code>sed</code>, <code>awk</code> or other commands into current Vim editor text, you can use <code>:r !</code> command. For example, if you want to insert <code>ls</code> command output at current position, you can type:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">:r !ls
</span></span></code></pre></div><h4 id="using--to-process-entire-file-content-through-external-command">Using <code>:%!</code> to Process Entire File Content Through External Command</h4>
<p>If you want to apply <code>sed</code> or <code>awk</code> command to entire file content and replace current file content, you can use <code>:%!</code> followed by corresponding command. For example, use <code>sed</code> command to replace all “foo” with “bar” in document:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">:%!sed <span class="s1">&#39;s/foo/bar/g&#39;</span>
</span></span></code></pre></div><h4 id="partial-usage">Partial Usage</h4>
<p>You can also specify a range to use external command only on certain parts of the file. For example, only process lines 5 to 10 through <code>awk</code> command:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">:5,10!awk <span class="s1">&#39;{print $1}&#39;</span>
</span></span></code></pre></div><hr>
<h3 id="macro-recording"><strong>Macro Recording</strong></h3>
<ol>
<li>Use <code>q</code> for macro recording in normal mode
<ul>
<li>Give register a name, say <code>a</code>, the full name of this register is <code>@a</code></li>
<li>Press <code>q</code> again to end recording after recording is complete</li>
<li>Type <code>@a</code> to execute macro, <code>@@</code> to execute last macro, <code>9@a</code> to execute macro 9 times</li>
</ul>
</li>
<li><strong>+1 operation</strong> on numbers. <code>&lt;C-a&gt;</code>, can be used with macro recording to write ordered lists:
<ul>
<li><code>1. sth</code>, then <code>yyp</code>, perform <code>&lt;C-a&gt;</code> on 1, repeat</li>
</ul>
</li>
</ol>
<hr>
<h3 id="other-features">Other Features</h3>
<ol>
<li><strong>Spell check</strong>. <code>:set spell! spelllang=en_us</code></li>
<li><code>:set rnu</code> set <strong>relative line numbers</strong>. Convenient for jumping</li>
</ol>
]]></content:encoded></item><item><title>Golang in short</title><link>https://www.parkerchenca.com/tech/golang-in-short/</link><pubDate>Thu, 10 Sep 2026 11:24:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/golang-in-short/</guid><description>Quick notes of GO</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
No need for digging a big hole, just use it.</p>
</blockquote>
<h2 id="golang-in-short">Golang in short</h2>
<hr>
<h3 id="go-is">Go is</h3>
<ol>
<li>A modern high-level programming language that resembles C</li>
<li>Open-source, compiled, statically typed, and memory-safe</li>
</ol>
<h3 id="go-has">Go has</h3>
<ol>
<li>Simple yet powerful package management (pulls directly from GitHub)</li>
<li>Built-in concurrency primitives</li>
<li>Garbage collection (GC)</li>
<li>Lightning-fast compilation</li>
<li>Minimal syntax</li>
<li>Cross-platform compilation</li>
</ol>
<h3 id="go-doesnt-have">Go doesn&rsquo;t have</h3>
<ol>
<li>Classes and inheritance</li>
<li>Function overloading</li>
<li>Implicit type conversions</li>
</ol>
<h3 id="i-use-go-to">I use Go to</h3>
<ol>
<li>Say goodbye to Java&rsquo;s verbose syntax</li>
<li>Build web services and microservices</li>
<li>Handle high-concurrency scenarios</li>
</ol>
<h3 id="go-is-perfect-for">Go is perfect for</h3>
<ol>
<li>Web services and RESTful APIs</li>
<li>Microservices architecture</li>
<li>Network programming and distributed systems</li>
</ol>
<h3 id="go-might-not-be-ideal-for">Go might not be ideal for</h3>
<ol>
<li>GUI desktop applications</li>
<li>Kernel development</li>
<li>Machine learning (Python has a stronger ecosystem)</li>
</ol>
<hr>
<h2 id="installing-go">Installing Go</h2>
<ol>
<li>Using OS package managers
<ul>
<li>Linux: <code>apt</code>, <code>yum</code>, <code>snap</code></li>
<li>macOS: <code>brew</code></li>
<li>Windows: <code>choco</code>, <code>scoop</code>, etc.</li>
</ul>
</li>
<li>Download official precompiled binaries
<ul>
<li>Already compiled, ready to use</li>
<li>Set up path and links manually</li>
</ul>
</li>
<li>Verify with <code>go version</code></li>
</ol>
<h3 id="hello-world">Hello World</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// This is a comment</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="cm">/* This is
</span></span></span><span class="line"><span class="cl"><span class="cm">   a multiline
</span></span></span><span class="line"><span class="cl"><span class="cm">   comment */</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">main</span><span class="w"> </span><span class="c1">// This is the main package</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// No semicolons at line endings</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="s">&#34;fmt&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="s">&#34;math&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w"> </span><span class="c1">// Importing other packages</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">const</span><span class="w"> </span><span class="nx">myConstant</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="c1">// Constants need explicit initialization</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;helloworld&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Package names -&gt; lowercase</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Lowercase in package -&gt; myConstant -&gt; package-private</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Capitalized -&gt; Println() -&gt; exported (public)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><h3 id="types">Types</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kt">bool</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kt">string</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kt">int</span><span class="w">  </span><span class="kt">int8</span><span class="w">  </span><span class="kt">int16</span><span class="w">  </span><span class="kt">int32</span><span class="w">  </span><span class="kt">int64</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kt">uint</span><span class="w"> </span><span class="kt">uint8</span><span class="w"> </span><span class="kt">uint16</span><span class="w"> </span><span class="kt">uint32</span><span class="w"> </span><span class="kt">uint64</span><span class="w"> </span><span class="kt">uintptr</span><span class="w"> </span><span class="c1">// Has pointers but no pointer arithmetic</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kt">byte</span><span class="w"> </span><span class="c1">// alias for uint8</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kt">rune</span><span class="w"> </span><span class="c1">// alias for int32</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">     </span><span class="c1">// Represents a Unicode code point</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">     </span><span class="c1">// From ancient Nordic &#34;rune&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kt">float32</span><span class="w"> </span><span class="kt">float64</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kt">complex64</span><span class="w"> </span><span class="kt">complex128</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Zero value for reference types is nil</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Type assertion</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">t</span><span class="p">,</span><span class="w"> </span><span class="nx">ok</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">variable</span><span class="p">.(</span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="c1">// Returns two values, ok indicates success</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                        </span><span class="c1">// Panics if ok is not captured and type is wrong</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Type conversion</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">myInt</span><span class="w"> </span><span class="kt">int32</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">42</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">myAnotherInt</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nb">int64</span><span class="p">(</span><span class="nx">myInt</span><span class="p">)</span><span class="w"> </span><span class="c1">// Type conversion</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                             </span><span class="c1">// No direct conversion between bool and int</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                             </span><span class="c1">// Generally, single characters and numbers can convert</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                             </span><span class="c1">// Otherwise, only conversions within same type family</span><span class="w">
</span></span></span></code></pre></div><h3 id="variables-and-functions">Variables and Functions</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">hi</span><span class="w"> </span><span class="kt">bool</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span><span class="c1">// Variables outside functions must have explicit types</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">myFunc</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span><span class="w"> </span><span class="nx">y</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">innerHi</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="s">&#34;hi&#34;</span><span class="w"> </span><span class="c1">// Inside functions, use := for type inference</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">const</span><span class="w"> </span><span class="nx">hiConst</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="s">&#34;hi again&#34;</span><span class="w"> </span><span class="c1">// Constants cannot use :=</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="nx">x</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="nx">y</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nx">MapFilter</span><span class="p">[</span><span class="nx">T</span><span class="w"> </span><span class="kt">any</span><span class="p">,</span><span class="w"> </span><span class="nx">R</span><span class="w"> </span><span class="nx">comparable</span><span class="p">](</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">slice</span><span class="w"> </span><span class="p">[]</span><span class="nx">T</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">mapper</span><span class="w"> </span><span class="kd">func</span><span class="p">(</span><span class="nx">T</span><span class="p">)</span><span class="w"> </span><span class="nx">R</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">predicate</span><span class="w"> </span><span class="kd">func</span><span class="p">(</span><span class="nx">R</span><span class="p">)</span><span class="w"> </span><span class="kt">bool</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w"> </span><span class="kd">func</span><span class="p">(</span><span class="nx">options</span><span class="w"> </span><span class="o">...</span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nx">filtered</span><span class="w"> </span><span class="p">[]</span><span class="nx">R</span><span class="p">,</span><span class="w"> </span><span class="nx">count</span><span class="w"> </span><span class="kt">int</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="kt">error</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Returns a function</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="kd">func</span><span class="p">(</span><span class="nx">options</span><span class="w"> </span><span class="o">...</span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nx">filtered</span><span class="w"> </span><span class="p">[]</span><span class="nx">R</span><span class="p">,</span><span class="w"> </span><span class="nx">count</span><span class="w"> </span><span class="kt">int</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="kt">error</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c1">// Implementation</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">return</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// A complete function signature example</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Note the second func starts parameters</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// The last func starts return type -&gt; returns a function</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// T is generic, R is constraint, but they&#39;re essentially the same thing</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="p">(</span><span class="nx">x</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">x</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="c1">// Anonymous function definition</span><span class="w">
</span></span></span></code></pre></div><h3 id="arrays-slices-and-maps">Arrays, Slices, and Maps</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// Arrays - fixed length</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">arr</span><span class="w"> </span><span class="p">[</span><span class="mi">5</span><span class="p">]</span><span class="kt">int</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">[</span><span class="mi">5</span><span class="p">]</span><span class="kt">int</span><span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span><span class="w"> </span><span class="mi">5</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">arr2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="p">[</span><span class="o">...</span><span class="p">]</span><span class="kt">int</span><span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">}</span><span class="w"> </span><span class="c1">// Compiler infers length</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Slices - dynamic length</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">slice</span><span class="w"> </span><span class="p">[]</span><span class="kt">int</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">[]</span><span class="kt">int</span><span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">slice2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nb">make</span><span class="p">([]</span><span class="kt">int</span><span class="p">,</span><span class="w"> </span><span class="mi">5</span><span class="p">)</span><span class="w">     </span><span class="c1">// Length 5</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">slice3</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nb">make</span><span class="p">([]</span><span class="kt">int</span><span class="p">,</span><span class="w"> </span><span class="mi">5</span><span class="p">,</span><span class="w"> </span><span class="mi">10</span><span class="p">)</span><span class="w"> </span><span class="c1">// Length 5, capacity 10</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Maps</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">m</span><span class="w"> </span><span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">int</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">int</span><span class="p">{</span><span class="s">&#34;one&#34;</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;two&#34;</span><span class="p">:</span><span class="w"> </span><span class="mi">2</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">m2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nb">make</span><span class="p">(</span><span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">int</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">m2</span><span class="p">[</span><span class="s">&#34;key&#34;</span><span class="p">]</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">42</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Check if key exists</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">value</span><span class="p">,</span><span class="w"> </span><span class="nx">exists</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">m</span><span class="p">[</span><span class="s">&#34;key&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">if</span><span class="w"> </span><span class="nx">exists</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nx">value</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><h3 id="control-flow">Control Flow</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// Only for loops exist</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// All parts of for loop are optional</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">for</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="p">&lt;</span><span class="w"> </span><span class="mi">10</span><span class="p">;</span><span class="w"> </span><span class="nx">i</span><span class="o">++</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Loop body</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Infinite loop</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">for</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Equivalent to while(true)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Condition loop</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">i</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">for</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="p">&lt;</span><span class="w"> </span><span class="mi">10</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">i</span><span class="o">++</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">for</span><span class="w"> </span><span class="nx">i</span><span class="p">,</span><span class="w"> </span><span class="nx">v</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">range</span><span class="w"> </span><span class="nx">expression</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="c1">// Iterate over iterables</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                                </span><span class="c1">// Similar to Python&#39;s for..in</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                                </span><span class="c1">// Directly provides index and value</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                                </span><span class="c1">// No enumerate function needed</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                                </span><span class="c1">// Use _, v to ignore index</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// if statement</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">if</span><span class="w"> </span><span class="nx">v</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">5</span><span class="p">;</span><span class="w"> </span><span class="nx">v</span><span class="w"> </span><span class="p">&lt;</span><span class="w"> </span><span class="mi">6</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="c1">// Can assign in condition</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Condition body</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// switch statement</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">switch</span><span class="w"> </span><span class="nx">x</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">5</span><span class="p">;</span><span class="w"> </span><span class="nx">x</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="c1">// x is optional</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">case</span><span class="w"> </span><span class="mi">1</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;one&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">case</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">:</span><span class="w">      </span><span class="c1">// Multiple values</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;two, three or four&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">default</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;other&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Type switch</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">switch</span><span class="w"> </span><span class="nx">v</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">x</span><span class="p">.(</span><span class="kd">type</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">case</span><span class="w"> </span><span class="kt">int</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;int: %d\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">v</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">case</span><span class="w"> </span><span class="kt">string</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;string: %s\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">v</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">default</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;unknown type\n&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><h3 id="defer-and-channels">Defer and Channels</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// defer - deferred execution (stack structure, LIFO)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">defer</span><span class="w"> </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">defer</span><span class="w"> </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">defer</span><span class="w"> </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nb">panic</span><span class="p">(</span><span class="s">&#34;!&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Output order: 3 2 1 panic</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// defer provides stack-based deferred execution</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// panic triggers deferred functions</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// channel - channels (queue structure, FIFO)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">channelExample</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">myChan</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nb">make</span><span class="p">(</span><span class="kd">chan</span><span class="w"> </span><span class="kt">int</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">)</span><span class="w"> </span><span class="c1">// Buffer size 2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">myChan</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="mi">10</span><span class="w"> </span><span class="c1">// 10 goes in</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">myChan</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="mi">20</span><span class="w"> </span><span class="c1">// then 20 goes in</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">took</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">&lt;-</span><span class="nx">myChan</span><span class="w">      </span><span class="c1">// took is 10</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="o">&lt;-</span><span class="nx">myChan</span><span class="p">)</span><span class="w"> </span><span class="c1">// 20</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">blockingChannel</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">ch</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nb">make</span><span class="p">(</span><span class="kd">chan</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="c1">// Unbuffered channel</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// ch &lt;- 1           // Will block! Need another goroutine to receive</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Correct approach</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">go</span><span class="w"> </span><span class="kd">func</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nx">ch</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="mi">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="o">&lt;-</span><span class="nx">ch</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Channels provide a queue-like or pipe-like structure</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// FIFO</span><span class="w">
</span></span></span></code></pre></div><h3 id="pointers">Pointers</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// Go has pointers</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Useful when referencing large data</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Go&#39;s design philosophy is very close to C-family languages</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Fun fact: When passing pointers to functions, both C and Go copy the pointer</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// All parameters are pass-by-value in both languages</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// But C++ has completely different reference passing mechanism</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">var</span><span class="w"> </span><span class="nx">myPtr</span><span class="w"> </span><span class="o">*</span><span class="kt">int</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// var anotherPtr uintptr  // uintptr is integer type, not pointer</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">i</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">42</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">myPtr</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="o">&amp;</span><span class="nx">i</span><span class="w"> </span><span class="c1">// Take address</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="o">*</span><span class="nx">myPtr</span><span class="p">)</span><span class="w"> </span><span class="c1">// Dereference, outputs 42</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">*</span><span class="nx">myPtr</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">43</span><span class="w">         </span><span class="c1">// Modify through pointer</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nx">i</span><span class="p">)</span><span class="w">      </span><span class="c1">// Outputs 43</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// No pointer arithmetic</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><h3 id="format-verbs">Format Verbs</h3>
<table>
	<thead>
			<tr>
					<th>Verb</th>
					<th>Description</th>
					<th>Example</th>
					<th>Output</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>%v (value)</td>
					<td>Default format</td>
					<td>Printf(&quot;%v&quot;, people)</td>
					<td>{zhangsan}</td>
			</tr>
			<tr>
					<td>%+v</td>
					<td>Adds field names for structs</td>
					<td>Printf(&quot;%+v&quot;, people)</td>
					<td>{Name:zhangsan}</td>
			</tr>
			<tr>
					<td>%#v</td>
					<td>Go syntax representation</td>
					<td>Printf(&quot;%#v&quot;, people)</td>
					<td>main.Human{Name:&ldquo;zhangsan&rdquo;}</td>
			</tr>
			<tr>
					<td>%T (type)</td>
					<td>Type in Go syntax</td>
					<td>Printf(&quot;%T&quot;, people)</td>
					<td>main.Human</td>
			</tr>
			<tr>
					<td>%%</td>
					<td>Percent sign</td>
					<td>Printf(&quot;%%&quot;)</td>
					<td>%</td>
			</tr>
			<tr>
					<td>%t (true)</td>
					<td>true or false</td>
					<td>Printf(&quot;%t&quot;, true)</td>
					<td>true</td>
			</tr>
			<tr>
					<td>%b (binary)</td>
					<td>Binary representation</td>
					<td>Printf(&quot;%b&quot;, 5)</td>
					<td>101</td>
			</tr>
			<tr>
					<td>%c (char)</td>
					<td>Unicode character</td>
					<td>Printf(&quot;%c&quot;, 0x4E2D)</td>
					<td>中</td>
			</tr>
			<tr>
					<td>%d (decimal)</td>
					<td>Decimal</td>
					<td>Printf(&quot;%d&quot;, 0x12)</td>
					<td>18</td>
			</tr>
			<tr>
					<td>%o (octal)</td>
					<td>Octal</td>
					<td>Printf(&quot;%o&quot;, 10)</td>
					<td>12</td>
			</tr>
			<tr>
					<td>%q (quote)</td>
					<td>Single-quoted character literal</td>
					<td>Printf(&quot;%q&quot;, 0x4E2D)</td>
					<td>&lsquo;中&rsquo;</td>
			</tr>
			<tr>
					<td>%x</td>
					<td>Hexadecimal, lowercase</td>
					<td>Printf(&quot;%x&quot;, 13)</td>
					<td>d</td>
			</tr>
			<tr>
					<td>%X</td>
					<td>Hexadecimal, uppercase</td>
					<td>Printf(&quot;%X&quot;, 13)</td>
					<td>D</td>
			</tr>
			<tr>
					<td>%U (unicode)</td>
					<td>Unicode format: U+1234</td>
					<td>Printf(&quot;%U&quot;, 0x4E2D)</td>
					<td>U+4E2D</td>
			</tr>
			<tr>
					<td>%b</td>
					<td>Binary exponent scientific notation</td>
					<td>Printf(&quot;%b&quot;, 10.5)</td>
					<td>5835037194198p-49</td>
			</tr>
			<tr>
					<td>%e</td>
					<td>Scientific notation</td>
					<td>Printf(&quot;%e&quot;, 10.2)</td>
					<td>1.020000e+01</td>
			</tr>
			<tr>
					<td>%E</td>
					<td>Scientific notation</td>
					<td>Printf(&quot;%E&quot;, 10.2)</td>
					<td>1.020000E+01</td>
			</tr>
			<tr>
					<td>%f (float)</td>
					<td>Decimal point, no exponent</td>
					<td>Printf(&quot;%f&quot;, 10.2)</td>
					<td>10.200000</td>
			</tr>
			<tr>
					<td>%g</td>
					<td>Compact format (%e or %f)</td>
					<td>Printf(&quot;%g&quot;, 10.20)</td>
					<td>10.2</td>
			</tr>
			<tr>
					<td>%G</td>
					<td>Compact format (%E or %f)</td>
					<td>Printf(&quot;%G&quot;, 10.20)</td>
					<td>10.2</td>
			</tr>
			<tr>
					<td>%s (string)</td>
					<td>String (string or []byte)</td>
					<td>Printf(&quot;%s&quot;, []byte(&ldquo;Go&rdquo;))</td>
					<td>Go</td>
			</tr>
			<tr>
					<td>%q</td>
					<td>Double-quoted string</td>
					<td>Printf(&quot;%q&quot;, &ldquo;Go&rdquo;)</td>
					<td>&ldquo;Go&rdquo;</td>
			</tr>
			<tr>
					<td>%x</td>
					<td>Hex, lowercase, two chars per byte</td>
					<td>Printf(&quot;%x&quot;, &ldquo;golang&rdquo;)</td>
					<td>676f6c616e67</td>
			</tr>
			<tr>
					<td>%X</td>
					<td>Hex, uppercase, two chars per byte</td>
					<td>Printf(&quot;%X&quot;, &ldquo;golang&rdquo;)</td>
					<td>676F6C616E67</td>
			</tr>
			<tr>
					<td>%p (pointer)</td>
					<td>Hexadecimal with 0x prefix</td>
					<td>Printf(&quot;%p&quot;, &amp;people)</td>
					<td>0x4f57f0</td>
			</tr>
			<tr>
					<td>+</td>
					<td>Always print sign; ASCII-only for %+q</td>
					<td>Printf(&quot;%+q&quot;, &ldquo;中文&rdquo;)</td>
					<td>&ldquo;\u4e2d\u6587&rdquo;</td>
			</tr>
			<tr>
					<td>-</td>
					<td>Pad with spaces on right (left-align)</td>
					<td></td>
					<td></td>
			</tr>
			<tr>
					<td>#</td>
					<td>Alternate format: 0 prefix for octal (%#o), 0x for hex (%#x), etc.</td>
					<td>Printf(&quot;%#U&quot;, &lsquo;中&rsquo;)</td>
					<td>U+4E2D &lsquo;中&rsquo;</td>
			</tr>
			<tr>
					<td>&rsquo; '</td>
					<td>Space for elided sign; spaces between bytes for hex</td>
					<td></td>
					<td></td>
			</tr>
			<tr>
					<td>0</td>
					<td>Pad with zeros; moves padding after sign for numbers</td>
					<td></td>
					<td></td>
			</tr>
	</tbody>
</table>
<p>Reference:</p>
<h3 id="string-formatting">String Formatting</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// %[flags][width][.precision]verb</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Width and alignment</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%5d\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="mi">42</span><span class="p">)</span><span class="w">      </span><span class="c1">// &#34;   42&#34; right-aligned, width 5</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%-5d\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="mi">42</span><span class="p">)</span><span class="w">     </span><span class="c1">// &#34;42   &#34; left-aligned, width 5</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%05d\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="mi">42</span><span class="p">)</span><span class="w">     </span><span class="c1">// &#34;00042&#34; zero-padded</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// String alignment</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;|%10s|\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;hello&#34;</span><span class="p">)</span><span class="w">   </span><span class="c1">// &#34;|     hello|&#34; right-aligned</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;|%-10s|\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;hello&#34;</span><span class="p">)</span><span class="w">  </span><span class="c1">// &#34;|hello     |&#34; left-aligned</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;|%10s|\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;你好&#34;</span><span class="p">)</span><span class="w">     </span><span class="c1">// &#34;|        你好|&#34; handles Chinese</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">pi</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mf">3.14159265359</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Decimal precision</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%.2f\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">pi</span><span class="p">)</span><span class="w">     </span><span class="c1">// &#34;3.14&#34; 2 decimal places</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%.4f\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">pi</span><span class="p">)</span><span class="w">     </span><span class="c1">// &#34;3.1416&#34; 4 decimal places (rounded)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%8.2f\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">pi</span><span class="p">)</span><span class="w">    </span><span class="c1">// &#34;    3.14&#34; width 8, 2 decimals</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%08.2f\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">pi</span><span class="p">)</span><span class="w">   </span><span class="c1">// &#34;00003.14&#34; zero-padded</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Scientific notation precision</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%.3e\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">pi</span><span class="p">)</span><span class="w">     </span><span class="c1">// &#34;3.142e+00&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%.3g\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="mf">0.00012345</span><span class="p">)</span><span class="w">  </span><span class="c1">// &#34;0.000123&#34; auto format</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// + flag: show sign</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%+d\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="mi">42</span><span class="p">)</span><span class="w">      </span><span class="c1">// &#34;+42&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%+f\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mf">3.14</span><span class="p">)</span><span class="w">   </span><span class="c1">// &#34;-3.140000&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// # flag: show base prefix</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%#x\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="mi">255</span><span class="p">)</span><span class="w">     </span><span class="c1">// &#34;0xff&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%#o\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="mi">8</span><span class="p">)</span><span class="w">       </span><span class="c1">// &#34;010&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%#b\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="mi">5</span><span class="p">)</span><span class="w">       </span><span class="c1">// &#34;0b101&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Space: add space for positive numbers</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;% d\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="mi">42</span><span class="p">)</span><span class="w">      </span><span class="c1">// &#34; 42&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;% d\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="o">-</span><span class="mi">42</span><span class="p">)</span><span class="w">     </span><span class="c1">// &#34;-42&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Making tables</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%-10s %8.2f %5d\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;Apple&#34;</span><span class="p">,</span><span class="w"> </span><span class="mf">3.99</span><span class="p">,</span><span class="w"> </span><span class="mi">10</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%-10s %8.2f %5d\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;Banana&#34;</span><span class="p">,</span><span class="w"> </span><span class="mf">12.5</span><span class="p">,</span><span class="w"> </span><span class="mi">5</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Output:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Apple          3.99    10</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Banana        12.50     5</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Dynamic width and precision</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">width</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">10</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">precision</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%*.*f\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">width</span><span class="p">,</span><span class="w"> </span><span class="nx">precision</span><span class="p">,</span><span class="w"> </span><span class="nx">pi</span><span class="p">)</span><span class="w">  </span><span class="c1">// Width and precision from variables</span><span class="w">
</span></span></span></code></pre></div><h3 id="structs">Structs</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">MyStruct</span><span class="w"> </span><span class="kd">struct</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">x</span><span class="w"> </span><span class="kt">int</span><span class="w">  </span><span class="c1">// Private field (package-visible)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">Y</span><span class="w"> </span><span class="kt">int</span><span class="w">  </span><span class="c1">// Public field (exported)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// No need for &#34;-&gt;&#34; with struct pointers, Go handles it</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Value receiver method</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">s</span><span class="w"> </span><span class="nx">MyStruct</span><span class="p">)</span><span class="w"> </span><span class="nf">myFunc</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span><span class="w"> </span><span class="nx">y</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="nx">s</span><span class="p">.</span><span class="nx">x</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">x</span><span class="p">,</span><span class="w"> </span><span class="nx">s</span><span class="p">.</span><span class="nx">Y</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">y</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Pointer receiver method</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">s</span><span class="w"> </span><span class="o">*</span><span class="nx">MyStruct</span><span class="p">)</span><span class="w"> </span><span class="nf">modify</span><span class="p">(</span><span class="nx">x</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">s</span><span class="p">.</span><span class="nx">x</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">x</span><span class="w">  </span><span class="c1">// Can modify original struct</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Pointer receivers can accept values and pointers</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Value receivers can also accept both, Go handles it automatically</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// In a sense, pointer parameters have &#34;broader&#34; acceptance</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Struct tags</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">User</span><span class="w"> </span><span class="kd">struct</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">Name</span><span class="w"> </span><span class="kt">string</span><span class="w"> </span><span class="s">`json:&#34;name&#34; xml:&#34;user-name&#34;`</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">Age</span><span class="w">  </span><span class="kt">int</span><span class="w">    </span><span class="s">`json:&#34;age,omitempty&#34;`</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">Pass</span><span class="w"> </span><span class="kt">string</span><span class="w"> </span><span class="s">`json:&#34;-&#34;`</span><span class="w"> </span><span class="c1">// Ignore this field</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Reading tags with reflection</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="s">&#34;reflect&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">field</span><span class="p">,</span><span class="w"> </span><span class="nx">_</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">reflect</span><span class="p">.</span><span class="nf">TypeOf</span><span class="p">(</span><span class="nx">User</span><span class="p">{}).</span><span class="nf">FieldByName</span><span class="p">(</span><span class="s">&#34;Name&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nx">field</span><span class="p">.</span><span class="nx">Tag</span><span class="p">.</span><span class="nf">Get</span><span class="p">(</span><span class="s">&#34;json&#34;</span><span class="p">))</span><span class="w">  </span><span class="c1">// &#34;name&#34;</span><span class="w">
</span></span></span></code></pre></div><h3 id="interfaces">Interfaces</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// Interfaces define method signatures</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// No explicit implementation needed - types automatically implement interfaces</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Interfaces can embed other interfaces</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">MyInterface</span><span class="w"> </span><span class="kd">interface</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nf">myAdd</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span><span class="w"> </span><span class="nx">y</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="kt">int</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">MyStruct</span><span class="w"> </span><span class="kd">struct</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">x</span><span class="w"> </span><span class="kt">int</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">y</span><span class="w"> </span><span class="kt">int</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">s</span><span class="w"> </span><span class="nx">MyStruct</span><span class="p">)</span><span class="w"> </span><span class="nf">myAdd</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span><span class="w"> </span><span class="nx">y</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="c1">// Implements myAdd</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="nx">x</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">y</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Now MyStruct implements MyInterface</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Empty interface</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">interface</span><span class="p">{}</span><span class="w"> </span><span class="c1">// or any (Go 1.18+)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Can store any type</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">x</span><span class="w"> </span><span class="kd">interface</span><span class="p">{}</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">42</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">x</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="s">&#34;hello&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">x</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">[]</span><span class="kt">int</span><span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Empty struct</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">y</span><span class="w"> </span><span class="kd">struct</span><span class="p">{}</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="kd">struct</span><span class="p">{}{}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Takes no memory, often used as signal</span><span class="w">
</span></span></span></code></pre></div><h3 id="error-handling">Error Handling</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// error is a built-in interface</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="kt">error</span><span class="w"> </span><span class="kd">interface</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nf">Error</span><span class="p">()</span><span class="w"> </span><span class="kt">string</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Functions typically return result and error</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">result</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nf">doSomething</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">if</span><span class="w"> </span><span class="nx">err</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;couldn&#39;t convert number: %v\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">err</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">return</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Custom error</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">MyError</span><span class="w"> </span><span class="kd">struct</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">msg</span><span class="w"> </span><span class="kt">string</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">e</span><span class="w"> </span><span class="nx">MyError</span><span class="p">)</span><span class="w"> </span><span class="nf">Error</span><span class="p">()</span><span class="w"> </span><span class="kt">string</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="nx">e</span><span class="p">.</span><span class="nx">msg</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Create errors with errors package</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="s">&#34;errors&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">errors</span><span class="p">.</span><span class="nf">New</span><span class="p">(</span><span class="s">&#34;something went wrong&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Format errors with fmt.Errorf</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">err</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Errorf</span><span class="p">(</span><span class="s">&#34;invalid value: %d&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">value</span><span class="p">)</span><span class="w">
</span></span></span></code></pre></div><h3 id="concurrency">Concurrency</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// Use go keyword to start goroutines</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">go</span><span class="w"> </span><span class="nf">say</span><span class="p">(</span><span class="s">&#34;world&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nf">say</span><span class="p">(</span><span class="s">&#34;hello&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Need to wait for goroutines to finish</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">time</span><span class="p">.</span><span class="nf">Sleep</span><span class="p">(</span><span class="nx">time</span><span class="p">.</span><span class="nx">Second</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// See Defer and Channels section for channel creation</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Sending to full channel blocks</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Receiving from empty channel blocks</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Close channel</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nb">close</span><span class="p">(</span><span class="nx">myChan</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Note: Only senders should close channels</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Use select to handle multiple channels</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Like concurrent switch</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// select blocks until one case can proceed</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// When multiple cases ready, randomly picks one</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">select</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">case</span><span class="w"> </span><span class="nx">v</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">&lt;-</span><span class="nx">ch1</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;received from ch1:&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">v</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">case</span><span class="w"> </span><span class="nx">ch2</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="nx">x</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;sent to ch2&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">case</span><span class="w"> </span><span class="o">&lt;-</span><span class="nx">quit</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;quit&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">return</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">default</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;no communication&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Mutex</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="s">&#34;sync&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">mu</span><span class="w"> </span><span class="nx">sync</span><span class="p">.</span><span class="nx">Mutex</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">mu</span><span class="p">.</span><span class="nf">Lock</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Critical section</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">mu</span><span class="p">.</span><span class="nf">Unlock</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Use defer to ensure unlock</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">mu</span><span class="p">.</span><span class="nf">Lock</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">defer</span><span class="w"> </span><span class="nx">mu</span><span class="p">.</span><span class="nf">Unlock</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Critical section</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Directional channels</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">send</span><span class="p">(</span><span class="nx">ch</span><span class="w"> </span><span class="kd">chan</span><span class="o">&lt;-</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">ch</span><span class="w"> </span><span class="o">&lt;-</span><span class="w"> </span><span class="mi">42</span><span class="w"> </span><span class="p">}</span><span class="w">      </span><span class="c1">// Send-only</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">recv</span><span class="p">(</span><span class="nx">ch</span><span class="w"> </span><span class="o">&lt;-</span><span class="kd">chan</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">val</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">&lt;-</span><span class="nx">ch</span><span class="w"> </span><span class="p">}</span><span class="w">   </span><span class="c1">// Receive-only</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Check if channel is closed</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">v</span><span class="p">,</span><span class="w"> </span><span class="nx">ok</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="o">&lt;-</span><span class="nx">ch</span><span class="w">  </span><span class="c1">// ok is false if channel closed and empty</span><span class="w">
</span></span></span></code></pre></div><h3 id="various-magic-">Various Magic 🪄</h3>
<h4 id="heading"><code>...</code></h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// 1. Variadic functions</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">sum</span><span class="p">(</span><span class="nx">nums</span><span class="w"> </span><span class="o">...</span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">total</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">for</span><span class="w"> </span><span class="nx">_</span><span class="p">,</span><span class="w"> </span><span class="nx">n</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">range</span><span class="w"> </span><span class="nx">nums</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nx">total</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="nx">n</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="nx">total</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Calling</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nf">sum</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">)</span><span class="w">      </span><span class="c1">// Can pass multiple</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nf">sum</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span><span class="w">            </span><span class="c1">// Can pass one</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nf">sum</span><span class="p">()</span><span class="w">             </span><span class="c1">// Can pass none</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// 2. Expanding slices</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">numbers</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="p">[]</span><span class="kt">int</span><span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">result</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nf">sum</span><span class="p">(</span><span class="nx">numbers</span><span class="o">...</span><span class="p">)</span><span class="w">  </span><span class="c1">// Expand to multiple arguments</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Common usage</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">slice1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="p">[]</span><span class="kt">int</span><span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">slice2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="p">[]</span><span class="kt">int</span><span class="p">{</span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">combined</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nb">append</span><span class="p">(</span><span class="nx">slice1</span><span class="p">,</span><span class="w"> </span><span class="nx">slice2</span><span class="o">...</span><span class="p">)</span><span class="w">  </span><span class="c1">// Expand slice2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// 3. Array literals</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">arr</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="p">[</span><span class="o">...</span><span class="p">]</span><span class="kt">int</span><span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span><span class="w"> </span><span class="mi">5</span><span class="p">}</span><span class="w">  </span><span class="c1">// Compiler calculates length, result is [5]int</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Useful with indices</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">arr</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="p">[</span><span class="o">...</span><span class="p">]</span><span class="kt">string</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="mi">0</span><span class="p">:</span><span class="w"> </span><span class="s">&#34;zero&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="mi">5</span><span class="p">:</span><span class="w"> </span><span class="s">&#34;five&#34;</span><span class="p">,</span><span class="w">   </span><span class="c1">// Array length is 6</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>Notes:</p>
<ol>
<li>Variadic parameter must be last</li>
<li>Inside function, variadic parameter is slice type</li>
<li>Types must match when expanding</li>
</ol>
<h4 id="initialization-tricks">Initialization Tricks</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// Initialize array with indices</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">arr</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="p">[</span><span class="mi">10</span><span class="p">]</span><span class="kt">int</span><span class="p">{</span><span class="mi">0</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">9</span><span class="p">:</span><span class="w"> </span><span class="mi">10</span><span class="p">}</span><span class="w">  </span><span class="c1">// 0th is 1, 9th is 10, rest are 0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Initialize map with keys</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">m</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">int</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="s">&#34;a&#34;</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="s">&#34;b&#34;</span><span class="p">:</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Partial struct initialization</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">Point</span><span class="w"> </span><span class="kd">struct</span><span class="p">{</span><span class="w"> </span><span class="nx">X</span><span class="p">,</span><span class="w"> </span><span class="nx">Y</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">p</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">Point</span><span class="p">{</span><span class="nx">Y</span><span class="p">:</span><span class="w"> </span><span class="mi">10</span><span class="p">}</span><span class="w">  </span><span class="c1">// X is 0, Y is 10</span><span class="w">
</span></span></span></code></pre></div><h4 id="iota-enumerations">iota Enumerations</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// iota starts at 0 in each const declaration</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">const</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">A</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="kc">iota</span><span class="w">  </span><span class="c1">// 0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">B</span><span class="w">         </span><span class="c1">// 1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">C</span><span class="w">         </span><span class="c1">// 2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Skip values</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">const</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">_</span><span class="w">  </span><span class="p">=</span><span class="w"> </span><span class="kc">iota</span><span class="w">  </span><span class="c1">// 0 (skip)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">KB</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="p">(</span><span class="mi">10</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="kc">iota</span><span class="p">)</span><span class="w">  </span><span class="c1">// 1 &lt;&lt; 10 = 1024</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">MB</span><span class="w">         </span><span class="c1">// 1 &lt;&lt; 20 = 1048576</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">GB</span><span class="w">         </span><span class="c1">// 1 &lt;&lt; 30 = 1073741824</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Bit flag enums</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">Permission</span><span class="w"> </span><span class="kt">int</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">const</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">Read</span><span class="w"> </span><span class="nx">Permission</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="kc">iota</span><span class="w">  </span><span class="c1">// 1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">Write</span><span class="w">                        </span><span class="c1">// 2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">Execute</span><span class="w">                      </span><span class="c1">// 4</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Usage</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">perm</span><span class="w"> </span><span class="nx">Permission</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">Read</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="nx">Write</span><span class="w">  </span><span class="c1">// Combine permissions</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Check permission</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">if</span><span class="w"> </span><span class="nx">perm</span><span class="o">&amp;</span><span class="nx">Read</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;Has read permission&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Add permission</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">perm</span><span class="w"> </span><span class="o">|=</span><span class="w"> </span><span class="nx">Execute</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Remove permission</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">perm</span><span class="w"> </span><span class="o">&amp;^=</span><span class="w"> </span><span class="nx">Write</span><span class="w">
</span></span></span></code></pre></div><h4 id="type-aliases-vs-type-definitions">Type Aliases vs Type Definitions</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// Type alias (Go 1.9+) - completely equivalent</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">MyInt</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="kt">int</span><span class="w">  </span><span class="c1">// MyInt is int, interchangeable</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Type definition - creates new type</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">MyInt</span><span class="w"> </span><span class="kt">int</span><span class="w">    </span><span class="c1">// MyInt is new type, cannot assign directly</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Example</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">Celsius</span><span class="w"> </span><span class="kt">float64</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">Fahrenheit</span><span class="w"> </span><span class="kt">float64</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">c</span><span class="w"> </span><span class="nx">Celsius</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">100</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">f</span><span class="w"> </span><span class="nx">Fahrenheit</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">212</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// f = c  // Error! Type mismatch</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">f</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nf">Fahrenheit</span><span class="p">(</span><span class="nx">c</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mi">9</span><span class="o">/</span><span class="mi">5</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">32</span><span class="p">)</span><span class="w">  </span><span class="c1">// Need explicit conversion</span><span class="w">
</span></span></span></code></pre></div><h4 id="make-vs-new">make vs new</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="nb">new</span><span class="p">(</span><span class="nx">T</span><span class="p">)</span><span class="w">      </span><span class="c1">// Returns *T, zero value allocation; commonly for simple structs</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nb">make</span><span class="p">(</span><span class="o">...</span><span class="p">)</span><span class="w">   </span><span class="c1">// Only for slice/map/chan, returns initialized value (not pointer)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Examples</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">p</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nb">new</span><span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="w">           </span><span class="c1">// *int, value is 0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nb">make</span><span class="p">([]</span><span class="kt">int</span><span class="p">,</span><span class="w"> </span><span class="mi">5</span><span class="p">)</span><span class="w">     </span><span class="c1">// []int, length 5, initialized</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">m</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nb">make</span><span class="p">(</span><span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="c1">// map[string]int, initialized</span><span class="w">
</span></span></span></code></pre></div><h3 id="go-gotchas-and-important-notes">Go Gotchas and Important Notes</h3>
<h4 id="slice-underlying-array-sharing">Slice Underlying Array Sharing</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// Passing slice copies slice header (pointer, len, cap), shares underlying array</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="p">[]</span><span class="kt">int</span><span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">t</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">s</span><span class="p">[:</span><span class="mi">2</span><span class="p">]</span><span class="w">         </span><span class="c1">// Shares underlying array with s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">s</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nb">append</span><span class="p">(</span><span class="nx">s</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">)</span><span class="w">   </span><span class="c1">// May trigger reallocation, t no longer shares</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Modifying shared underlying array</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="p">[]</span><span class="kt">int</span><span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">,</span><span class="w"> </span><span class="mi">5</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">t</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">s</span><span class="p">[</span><span class="mi">1</span><span class="p">:</span><span class="mi">3</span><span class="p">]</span><span class="w">  </span><span class="c1">// [2, 3]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">t</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">99</span><span class="w">    </span><span class="c1">// s becomes [1, 99, 3, 4, 5]</span><span class="w">
</span></span></span></code></pre></div><h4 id="map-randomness">Map Randomness</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// Map iteration order is random, don&#39;t rely on order</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">m</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">int</span><span class="p">{</span><span class="s">&#34;a&#34;</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;b&#34;</span><span class="p">:</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;c&#34;</span><span class="p">:</span><span class="w"> </span><span class="mi">3</span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">for</span><span class="w"> </span><span class="nx">k</span><span class="p">,</span><span class="w"> </span><span class="nx">v</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">range</span><span class="w"> </span><span class="nx">m</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nx">k</span><span class="p">,</span><span class="w"> </span><span class="nx">v</span><span class="p">)</span><span class="w">  </span><span class="c1">// Order may differ each run</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Cannot take address of map elements</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// &amp;m[&#34;key&#34;]  // Compile error: map values not addressable</span><span class="w">
</span></span></span></code></pre></div><h4 id="string-bytes-vs-characters">String Bytes vs Characters</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// len(string) returns byte count, not character count</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="s">&#34;你好&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="nx">s</span><span class="p">))</span><span class="w">  </span><span class="c1">// 6 (3 bytes per Chinese character)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// for range string iterates by rune (UTF-8 decoded)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">for</span><span class="w"> </span><span class="nx">i</span><span class="p">,</span><span class="w"> </span><span class="nx">r</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">range</span><span class="w"> </span><span class="s">&#34;你好&#34;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%d: %c\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="nx">i</span><span class="p">,</span><span class="w"> </span><span class="nx">r</span><span class="p">)</span><span class="w">  </span><span class="c1">// 0: 你, 3: 好</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// s[i] gives byte</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%x\n&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;你&#34;</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span><span class="w">  </span><span class="c1">// e4 (first byte)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Strings are immutable, convert to []byte or []rune to modify</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">s</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="s">&#34;hello&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// s[0] = &#39;H&#39;  // Error!</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">bs</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="p">[]</span><span class="nb">byte</span><span class="p">(</span><span class="nx">s</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">bs</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="sc">&#39;H&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">s</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nb">string</span><span class="p">(</span><span class="nx">bs</span><span class="p">)</span><span class="w">  </span><span class="c1">// &#34;Hello&#34;</span><span class="w">
</span></span></span></code></pre></div><h4 id="interface-nil-pitfall">Interface nil Pitfall</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// Interface value is (type, data) pair</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// When type != nil, even if data == nil, interface is not nil</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">MyErr</span><span class="w"> </span><span class="kd">struct</span><span class="p">{}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">e</span><span class="w"> </span><span class="o">*</span><span class="nx">MyErr</span><span class="p">)</span><span class="w"> </span><span class="nf">Error</span><span class="p">()</span><span class="w"> </span><span class="kt">string</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="s">&#34;error&#34;</span><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">e</span><span class="w"> </span><span class="kt">error</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nx">e</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="kc">nil</span><span class="p">)</span><span class="w">  </span><span class="c1">// true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">pe</span><span class="w"> </span><span class="o">*</span><span class="nx">MyErr</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="kc">nil</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">e</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">pe</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nx">e</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="kc">nil</span><span class="p">)</span><span class="w">  </span><span class="c1">// false! type=*MyErr, data=nil</span><span class="w">
</span></span></span></code></pre></div><h4 id="loop-variable-pitfall">Loop Variable Pitfall</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// Loop variables reuse same memory location</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Be careful in goroutines/closures</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Wrong</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">for</span><span class="w"> </span><span class="nx">i</span><span class="p">,</span><span class="w"> </span><span class="nx">v</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">range</span><span class="w"> </span><span class="p">[]</span><span class="kt">int</span><span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">}</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">go</span><span class="w"> </span><span class="kd">func</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nx">i</span><span class="p">,</span><span class="w"> </span><span class="nx">v</span><span class="p">)</span><span class="w">  </span><span class="c1">// May all print 2, 3</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Correct: rebind</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">for</span><span class="w"> </span><span class="nx">i</span><span class="p">,</span><span class="w"> </span><span class="nx">v</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">range</span><span class="w"> </span><span class="p">[]</span><span class="kt">int</span><span class="p">{</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">}</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">i</span><span class="p">,</span><span class="w"> </span><span class="nx">v</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">i</span><span class="p">,</span><span class="w"> </span><span class="nx">v</span><span class="w">  </span><span class="c1">// Create new local variables</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">go</span><span class="w"> </span><span class="kd">func</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nx">i</span><span class="p">,</span><span class="w"> </span><span class="nx">v</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><h4 id="method-call-auto-conversion">Method Call Auto-conversion</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// Compiler automatically handles value/pointer conversion</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">S</span><span class="w"> </span><span class="kd">struct</span><span class="p">{</span><span class="w"> </span><span class="nx">n</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">s</span><span class="w"> </span><span class="o">*</span><span class="nx">S</span><span class="p">)</span><span class="w"> </span><span class="nf">Inc</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">s</span><span class="p">.</span><span class="nx">n</span><span class="o">++</span><span class="w"> </span><span class="p">}</span><span class="w">  </span><span class="c1">// Pointer receiver</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">v</span><span class="w"> </span><span class="nx">S</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">v</span><span class="p">.</span><span class="nf">Inc</span><span class="p">()</span><span class="w">    </span><span class="c1">// Compiler converts to (&amp;v).Inc()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">p</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="o">&amp;</span><span class="nx">S</span><span class="p">{}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">(</span><span class="o">*</span><span class="nx">p</span><span class="p">).</span><span class="nf">Inc</span><span class="p">()</span><span class="w"> </span><span class="c1">// Works but unnecessary</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">p</span><span class="p">.</span><span class="nf">Inc</span><span class="p">()</span><span class="w">    </span><span class="c1">// Direct call</span><span class="w">
</span></span></span></code></pre></div><h4 id="struct-embedding-anonymous-fields">Struct Embedding (Anonymous Fields)</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// Embedded field methods and properties are &#34;promoted&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">A</span><span class="w"> </span><span class="kd">struct</span><span class="p">{</span><span class="w"> </span><span class="nx">X</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">a</span><span class="w"> </span><span class="nx">A</span><span class="p">)</span><span class="w"> </span><span class="nf">Show</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nx">a</span><span class="p">.</span><span class="nx">X</span><span class="p">)</span><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">B</span><span class="w"> </span><span class="kd">struct</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">A</span><span class="w">          </span><span class="c1">// Anonymous embedding</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">Y</span><span class="w"> </span><span class="kt">int</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">b</span><span class="w"> </span><span class="nx">B</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">b</span><span class="p">.</span><span class="nx">X</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">1</span><span class="w">        </span><span class="c1">// Direct access, equivalent to b.A.X</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">b</span><span class="p">.</span><span class="nf">Show</span><span class="p">()</span><span class="w">       </span><span class="c1">// Calls A&#39;s method</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// With name conflicts, must specify explicitly</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">type</span><span class="w"> </span><span class="nx">C</span><span class="w"> </span><span class="kd">struct</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">A</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">X</span><span class="w"> </span><span class="kt">int</span><span class="w">      </span><span class="c1">// Shadows A.X</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">var</span><span class="w"> </span><span class="nx">c</span><span class="w"> </span><span class="nx">C</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">c</span><span class="p">.</span><span class="nx">X</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">1</span><span class="w">        </span><span class="c1">// Accesses C.X</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nx">c</span><span class="p">.</span><span class="nx">A</span><span class="p">.</span><span class="nx">X</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="mi">2</span><span class="w">      </span><span class="c1">// Accesses A.X</span><span class="w">
</span></span></span></code></pre></div><h4 id="init-functions-and-package-imports">init Functions and Package Imports</h4>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// init() executes automatically on package load</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// Order: imported package init -&gt; current package init -&gt; main</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">package</span><span class="w"> </span><span class="nx">main</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">_</span><span class="w"> </span><span class="s">&#34;database/sql&#34;</span><span class="w">      </span><span class="c1">// Only execute init, don&#39;t use exports</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">_</span><span class="w"> </span><span class="s">&#34;github.com/go-sql-driver/mysql&#34;</span><span class="w">  </span><span class="c1">// Register MySQL driver</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">init</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">&#34;main init&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Database driver already registered in init</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>]]></content:encoded></item><item><title>Basic Makefile</title><link>https://www.parkerchenca.com/tech/basic-makefile/</link><pubDate>Thu, 10 Sep 2026 11:23:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/basic-makefile/</guid><description>The first step to understand makefile</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
I often noticed Makefile files in the root directory when browsing open-source projects on GitHub. For a long time, I thought it was some kind of sophisticated &ldquo;magic tool&rdquo;. So during my spare time at my internship, I decided to learn some basic syntax&hellip; only to discover that it&rsquo;s actually like a &ldquo;recipe&rdquo; for compilation - to get a target file (the dish), you need some dependencies (ingredients) and commands (cooking instructions). Anyway, at least now I can understand it (mostly).</p>
</blockquote>
<h2 id="make">Make</h2>
<h3 id="basic-rules">Basic Rules</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="nf">target</span><span class="o">:</span> <span class="n">dependencies</span> ..
</span></span><span class="line"><span class="cl"><span class="err">[tab][Command]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">TARGET</span> <span class="o">=</span> main
</span></span><span class="line"><span class="cl"><span class="nf">main</span><span class="o">:</span> <span class="n">hello</span>.<span class="n">o</span> <span class="n">world</span>.<span class="n">o</span>   <span class="c"># will be run by default as the first target
</span></span></span><span class="line"><span class="cl">    gcc $^ -o <span class="k">$(</span>TARGET<span class="k">)</span> <span class="c1"># treat these as normal bash commands</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">hello.o</span><span class="o">:</span> <span class="n">hello</span>.<span class="n">c</span>
</span></span><span class="line"><span class="cl">    gcc -c hello.c      <span class="c1"># -c for compile only</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">world.o</span><span class="o">:</span> <span class="n">world</span>.<span class="n">c</span>
</span></span><span class="line"><span class="cl">    gcc -c world.c
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">clean</span><span class="o">:</span>                  <span class="c"># will not be run unless &#34;make clean&#34;
</span></span></span><span class="line"><span class="cl">    rm -f <span class="k">$(</span>wildcard *.o<span class="k">)</span> <span class="k">$(</span>TARGET<span class="k">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">.PHONY</span><span class="o">:</span> <span class="n">clean</span>
</span></span></code></pre></div><h3 id="common-cli-parameters">Common CLI Parameters</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="err">-v</span>
</span></span><span class="line"><span class="cl"><span class="err">-n</span> <span class="err">--just-print</span>        <span class="c"># Print commands without executing
</span></span></span><span class="line"><span class="cl"><span class="err">-p</span>                     <span class="c"># Output makefile data (lots of info)
</span></span></span><span class="line"><span class="cl"><span class="err">-t</span> <span class="err">--touch</span>             <span class="c"># Update file timestamps without changing targets (dry run)
</span></span></span><span class="line"><span class="cl"><span class="err">-q</span> <span class="err">--question</span>          <span class="c"># Check if target exists. Do nothing if yes, print error if no
</span></span></span><span class="line"><span class="cl">                       <span class="c1"># Usually used with -qp</span>
</span></span><span class="line"><span class="cl"><span class="err">-W</span> <span class="err">--what-if</span> <span class="err">&lt;file&gt;</span>    <span class="c"># Pretend this file was just modified, trigger related rules
</span></span></span><span class="line"><span class="cl"><span class="err">-B</span>                     <span class="c"># Rebuild everything
</span></span></span><span class="line"><span class="cl"><span class="err">-b</span> <span class="err">-m</span>                  <span class="c"># Used to ignore compatibility between different make versions
</span></span></span><span class="line"><span class="cl"><span class="nv">-debug</span><span class="o">=[</span>option<span class="o">]</span>        <span class="c1"># Debug mode</span>
</span></span><span class="line"><span class="cl">                       <span class="c1"># option can be: a(all), b(basic), v(verbose)</span>
</span></span><span class="line"><span class="cl">                       <span class="c1"># i(implicit), j(jobs), m(makefile)</span>
</span></span><span class="line"><span class="cl">                       <span class="c1"># -d = -debug=a</span>
</span></span><span class="line"><span class="cl"><span class="err">-e</span> <span class="nv">var</span><span class="o">=</span>sth             <span class="c1"># Override environment variable values</span>
</span></span><span class="line"><span class="cl"><span class="err">-h</span>                     <span class="c"># Help me!
</span></span></span><span class="line"><span class="cl"><span class="err">-f</span> <span class="err">&lt;file&gt;</span>              <span class="c"># Execute specific makefile
</span></span></span><span class="line"><span class="cl"><span class="err">-i</span>                     <span class="c"># Ignore errors
</span></span></span><span class="line"><span class="cl"><span class="err">-I</span> <span class="err">--include-dir</span> <span class="err">&lt;dir&gt;</span> <span class="c"># Specify make search directory
</span></span></span><span class="line"><span class="cl"><span class="err">-k</span> <span class="err">--keep-going</span>        <span class="c"># Continue on errors, except missing dependencies
</span></span></span><span class="line"><span class="cl"><span class="err">-s</span> <span class="err">--silent</span>
</span></span><span class="line"><span class="cl"><span class="err">-j</span> <span class="err">--jobs</span>              <span class="c"># Parallel compilation when dependencies allow
</span></span></span><span class="line"><span class="cl">                       <span class="c1"># make will try to parallelize as much as possible by default</span>
</span></span></code></pre></div><h3 id="special-syntax">Special Syntax</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="k">$&lt;</span>                  <span class="c"># First item in dependencies
</span></span></span><span class="line"><span class="cl">                    <span class="c1"># Note: if target is matched via %,</span>
</span></span><span class="line"><span class="cl">                    <span class="c1"># $&lt; represents all matched items</span>
</span></span><span class="line"><span class="cl"><span class="err">$^</span>                  <span class="c"># All dependencies
</span></span></span><span class="line"><span class="cl"><span class="k">$?</span>                  <span class="c"># All dependencies that are newer than target
</span></span></span><span class="line"><span class="cl"><span class="k">$+</span>                  <span class="c"># All dependencies without deduplication
</span></span></span><span class="line"><span class="cl"><span class="k">$*</span>                  <span class="c"># The part matched by %
</span></span></span><span class="line"><span class="cl"><span class="k">$@</span>                  <span class="c"># The target
</span></span></span><span class="line"><span class="cl"><span class="k">$%</span>                  <span class="c"># Target member name (only for archive files)
</span></span></span><span class="line"><span class="cl"><span class="k">$$</span>                  <span class="c"># Escape $ character
</span></span></span><span class="line"><span class="cl"><span class="k">$(</span><span class="nv">wildcard</span> *.<span class="nv">c</span><span class="k">)</span>     <span class="c"># Use wildcards
</span></span></span><span class="line"><span class="cl"><span class="nf">$(source</span><span class="o">:</span>.<span class="n">c</span>=.<span class="n">o</span>)     <span class="c"># Change suffix of variable
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">:=</span>                  <span class="c"># Immediate expansion of $() expressions (no variable hoisting)
</span></span></span><span class="line"><span class="cl"><span class="err">?=</span>                  <span class="c"># Assign only if not already defined
</span></span></span><span class="line"><span class="cl"><span class="err">+=</span>                  <span class="c"># Append to variable value (with leading space)
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">%</span>                   <span class="c"># Wildcard in pattern rules
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">@[command]</span>          <span class="c"># Execute command silently
</span></span></span><span class="line"><span class="cl"><span class="err">-[command]</span>          <span class="c"># Ignore errors, continue running
</span></span></span><span class="line"><span class="cl"><span class="err">[command];[command]</span> <span class="c"># Similar to pipeline (&#34;|&#34;)
</span></span></span><span class="line"><span class="cl">                    <span class="c1"># If written on separate lines, executed separately</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">override var </span><span class="o">:</span>= <span class="n">new</span>-<span class="n">value</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># $ with uppercase D(Directory) and F(File)
</span></span></span><span class="line"><span class="cl"><span class="c"># Further specify the scope of dependency strings
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">dir/foo.o</span><span class="o">:</span> ...
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># Need parentheses to avoid ambiguity
</span></span></span><span class="line"><span class="cl"><span class="k">$(</span>@<span class="nv">D</span><span class="k">)</span>               <span class="c"># dir/foo.o -&gt; dir
</span></span></span><span class="line"><span class="cl"><span class="k">$(</span>@<span class="nv">F</span><span class="k">)</span>               <span class="c"># dir/foo.o -&gt; foo.o
</span></span></span></code></pre></div><h3 id="pattern-rules">Pattern Rules</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="nf">%.o</span><span class="o">:</span> %.<span class="n">c</span>    <span class="c"># % means &#34;match&#34;, represents &#34;any string&#34;
</span></span></span><span class="line"><span class="cl">            <span class="c1"># Meaning: to build .o file, its dependency is corresponding .c file</span>
</span></span><span class="line"><span class="cl">            <span class="c1"># No directory search performed</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># Study these examples for better understanding
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">src/eat</span>
</span></span><span class="line"><span class="cl"><span class="err">e%t</span>
</span></span><span class="line"><span class="cl"><span class="err">%</span> <span class="err">-&gt;</span> <span class="err">src/a</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># then, % is passed to another place...
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">c%r</span> <span class="err">-&gt;</span> <span class="err">csrc/ar</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># but if there is a nested % pattern on the original side...
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">c%r</span> <span class="err">-&gt;</span> <span class="err">src/car</span>  <span class="c"># % should be &#34;src/a&#34;
</span></span></span><span class="line"><span class="cl">                <span class="c1"># but &#34;src/&#34; will be removed before matching patterns</span>
</span></span><span class="line"><span class="cl">                <span class="c1"># so in this situation, % is &#34;a&#34;</span>
</span></span><span class="line"><span class="cl">                <span class="c1"># this rule also applies to the first step</span>
</span></span></code></pre></div><h3 id="functions">Functions</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="c"># Basic syntax
</span></span></span><span class="line"><span class="cl"><span class="k">$(</span>&lt;<span class="nv">function</span>&gt; &lt;<span class="nv">arguments</span>&gt;<span class="k">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># Can also be written as
</span></span></span><span class="line"><span class="cl"><span class="err">${&lt;function&gt;</span> <span class="err">&lt;arguments&gt;}</span>   <span class="c"># Perhaps more readable
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">$(</span><span class="nv">patsubst</span> %.<span class="nv">c</span>,%.<span class="nv">o</span>,<span class="k">$(</span><span class="nv">source</span><span class="k">))</span>  <span class="c"># Better demonstrates % syntax behavior
</span></span></span><span class="line"><span class="cl">                               <span class="c1"># patsubst = pattern substitute</span>
</span></span><span class="line"><span class="cl">                               <span class="c1"># For any .c file, replace with corresponding .o file</span>
</span></span><span class="line"><span class="cl">                               <span class="c1"># Scope is $(source), which should be text</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># Common functions
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">subst</span> <span class="err">&lt;from&gt;,&lt;to&gt;,&lt;text&gt;</span>    <span class="c"># Substitute text
</span></span></span><span class="line"><span class="cl"><span class="err">strip</span> <span class="err">&lt;text&gt;</span>                <span class="c"># Remove spaces
</span></span></span><span class="line"><span class="cl"><span class="err">findstring</span> <span class="err">&lt;find&gt;,&lt;in&gt;</span>      <span class="c"># Find substring, return &lt;find&gt; if found
</span></span></span><span class="line"><span class="cl"><span class="err">filter</span> <span class="err">&lt;pattern...&gt;,&lt;text&gt;</span>  <span class="c"># Can pass multiple patterns
</span></span></span><span class="line"><span class="cl"><span class="err">filter-out</span> <span class="err">&lt;pattern...&gt;,&lt;text&gt;</span> <span class="c"># Reverse filter, keeps unmatched items
</span></span></span><span class="line"><span class="cl"><span class="err">sort</span> <span class="err">&lt;list&gt;</span>                 <span class="c"># Default ascending order
</span></span></span><span class="line"><span class="cl"><span class="err">word</span> <span class="err">&lt;n&gt;,&lt;text&gt;</span>             <span class="c"># Get nth word (a.c b.c c.c -&gt; b.c)
</span></span></span><span class="line"><span class="cl"><span class="err">wordlist</span> <span class="err">&lt;s&gt;,&lt;e&gt;,&lt;text&gt;</span>     <span class="c"># Slice
</span></span></span><span class="line"><span class="cl"><span class="err">words</span> <span class="err">&lt;text&gt;</span>                <span class="c"># Count words
</span></span></span><span class="line"><span class="cl"><span class="err">firstword</span> <span class="err">&lt;text&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">dir</span> <span class="err">&lt;names...&gt;</span>              <span class="c"># Extract directory from filename
</span></span></span><span class="line"><span class="cl"><span class="err">notdir</span> <span class="err">&lt;names...&gt;</span>           <span class="c"># Remove directory part, keep filename only
</span></span></span><span class="line"><span class="cl"><span class="err">suffix</span> <span class="err">&lt;names...&gt;</span>           <span class="c"># Extract suffix
</span></span></span><span class="line"><span class="cl"><span class="err">basename</span> <span class="err">&lt;names...&gt;</span>         <span class="c"># Extract name without suffix (prefix)
</span></span></span><span class="line"><span class="cl"><span class="err">addsuffix</span> <span class="err">&lt;suffix&gt;,&lt;names...&gt;</span> <span class="c"># Add suffix
</span></span></span><span class="line"><span class="cl"><span class="err">addprefix</span> <span class="err">&lt;prefix&gt;,&lt;names...&gt;</span>
</span></span><span class="line"><span class="cl"><span class="err">join</span> <span class="err">&lt;list1&gt;,&lt;list2&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">origin</span> <span class="err">&lt;variable&gt;</span>           <span class="c"># Where did this variable come from?
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">shell</span> <span class="err">&lt;command&gt;</span>             <span class="c"># Execute command in shell
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">error</span> <span class="err">&lt;text</span> <span class="err">...&gt;</span>            <span class="c"># Generate error message, but doesn&#39;t abort
</span></span></span><span class="line"><span class="cl"><span class="err">warning</span> <span class="err">&lt;text</span> <span class="err">...&gt;</span>          <span class="c"># Generate warning message
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># Iteration
</span></span></span><span class="line"><span class="cl"><span class="err">foreach</span> <span class="err">&lt;var&gt;,&lt;list&gt;,&lt;text&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">names</span> <span class="o">:=</span> a b c d
</span></span><span class="line"><span class="cl"><span class="nv">files</span> <span class="o">:=</span> <span class="k">$(</span>foreach n,<span class="k">$(</span>names<span class="k">)</span>,<span class="k">$(</span>n<span class="k">)</span>.o<span class="k">)</span>  <span class="c1"># a.o b.o c.o d.o</span>
</span></span></code></pre></div><h3 id="custom-functions-with-call">Custom Functions with call</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="err">call</span> <span class="err">&lt;expression&gt;,&lt;parm1&gt;,&lt;parm2&gt;,...,&lt;parmn&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># Examples are easier to understand
</span></span></span><span class="line"><span class="cl"><span class="nv">reverse</span> <span class="o">=</span> <span class="k">$(</span>2<span class="k">)</span> <span class="k">$(</span>1<span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="nv">foo</span> <span class="o">=</span> <span class="k">$(</span>call reverse,a,b<span class="k">)</span>  <span class="c1"># $(foo) -&gt; b a</span>
</span></span></code></pre></div><h3 id="special-variables">Special Variables</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="err">VPATH</span>                            <span class="c"># Set default search path
</span></span></span><span class="line"><span class="cl"><span class="c"># Syntax: vpath &lt;pattern&gt; &lt;directories&gt;
</span></span></span><span class="line"><span class="cl"><span class="c"># Example: vpath %.h src:../headers:lib  # Directories separated by colon (:)
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># Can actively set paths
</span></span></span><span class="line"><span class="cl"><span class="c"># Advantage: if file not found, will search in VPATH
</span></span></span><span class="line"><span class="cl"><span class="nv">VPATH</span> <span class="o">=</span> src
</span></span><span class="line"><span class="cl"><span class="nv">BUILD_DIR</span> <span class="o">=</span> build
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">$(BUILD_DIR)/%.o</span><span class="o">:</span> %.<span class="n">c</span>
</span></span><span class="line"><span class="cl">    gcc -c $&lt; -o <span class="nv">$@</span>
</span></span></code></pre></div><h3 id="sub-makefiles">Sub-Makefiles</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="nf">subsystem</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">    <span class="nb">cd</span> subdir <span class="o">&amp;&amp;</span> <span class="k">$(</span>MAKE<span class="k">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># Equivalent to
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">subsystem</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">    <span class="k">$(</span>MAKE<span class="k">)</span> -C subdir
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># Execute make in subsystem
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">export </span><span class="nv">VAR</span> <span class="o">=</span> value     <span class="c1"># Pass VAR to subsystem</span>
</span></span><span class="line"><span class="cl"><span class="err">un</span><span class="k">export </span><span class="err">VAR_PRIVATE</span>   <span class="c"># Don&#39;t pass this variable
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># $(SHELL) and $(MAKEFLAGS) are always passed to subsystems
</span></span></span></code></pre></div><h3 id="define-directive">Define Directive</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="err">define</span> <span class="err">reusable</span>
</span></span><span class="line"><span class="cl"><span class="err">dosth..</span>
</span></span><span class="line"><span class="cl"><span class="err">dosth..</span>
</span></span><span class="line"><span class="cl"><span class="err">endef</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">$(</span><span class="nv">reusable</span><span class="k">)</span>
</span></span></code></pre></div><h3 id="conditionals">Conditionals</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="c"># Similar to bash syntax
</span></span></span><span class="line"><span class="cl"><span class="err">ifeq</span> <span class="err">(var1,</span> <span class="err">var2)</span>
</span></span><span class="line"><span class="cl">    <span class="err">[command]</span>
</span></span><span class="line"><span class="cl"><span class="err">else</span>
</span></span><span class="line"><span class="cl">    <span class="err">[command]</span>
</span></span><span class="line"><span class="cl"><span class="err">endif</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># Available keywords
</span></span></span><span class="line"><span class="cl"><span class="err">ifeq</span> <span class="err">ifneq</span> <span class="err">ifdef</span> <span class="err">ifndef</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># if as a function
</span></span></span><span class="line"><span class="cl"><span class="k">$(</span><span class="nv">if</span> &lt;<span class="nv">condition</span>&gt;,&lt;<span class="nv">then</span>-<span class="nv">part</span>&gt;<span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="k">$(</span><span class="nv">if</span> &lt;<span class="nv">condition</span>&gt;,&lt;<span class="nv">then</span>-<span class="nv">part</span>&gt;,&lt;<span class="nv">else</span>-<span class="nv">part</span>&gt;<span class="k">)</span>
</span></span></code></pre></div><h3 id="implicit-rules">Implicit Rules</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="c"># Implicit rules use these predefined variables:
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">CC</span> <span class="o">=</span> gcc        <span class="c1"># C compiler</span>
</span></span><span class="line"><span class="cl"><span class="nv">CXX</span> <span class="o">=</span> g++       <span class="c1"># C++ compiler</span>
</span></span><span class="line"><span class="cl"><span class="nv">CFLAGS</span> <span class="o">=</span>        <span class="c1"># C compile options</span>
</span></span><span class="line"><span class="cl"><span class="nv">CXXFLAGS</span> <span class="o">=</span>      <span class="c1"># C++ compile options</span>
</span></span><span class="line"><span class="cl"><span class="nv">LDFLAGS</span> <span class="o">=</span>       <span class="c1"># Linker options</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># Only need to define dependencies, compile rules apply automatically
</span></span></span><span class="line"><span class="cl"><span class="nv">CFLAGS</span> <span class="o">=</span> -Wall -O2
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">main</span><span class="o">:</span> <span class="n">main</span>.<span class="n">o</span> <span class="n">utils</span>.<span class="n">o</span>  <span class="c"># Implicit rules automatically compile .c → .o
</span></span></span><span class="line"><span class="cl">    <span class="k">$(</span>CC<span class="k">)</span> $^ -o <span class="nv">$@</span>    <span class="c1"># Linking rules need to be written manually</span>
</span></span><span class="line"><span class="cl">                      <span class="c1"># (implicit rules only handle single file compilation)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># View all implicit rules
</span></span></span><span class="line"><span class="cl"><span class="err">make</span> <span class="err">-p</span> <span class="err">|</span> <span class="err">grep</span> <span class="s2">&#34;^%&#34;</span>  <span class="c"># Display all pattern rules
</span></span></span></code></pre></div><h3 id="include-directive">Include Directive</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="err">include</span> <span class="err">file1.mk</span> <span class="err">file2.mk</span>
</span></span><span class="line"><span class="cl"><span class="err">-include</span> <span class="err">optional.mk</span>  <span class="c"># Don&#39;t error if file doesn&#39;t exist
</span></span></span></code></pre></div><h3 id="special-targets">Special Targets</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="nf">.PHONY</span><span class="o">:</span> <span class="n">clean</span> <span class="n">test</span> <span class="n">install</span>      <span class="c"># Declare phony targets
</span></span></span><span class="line"><span class="cl"><span class="nf">.PRECIOUS</span><span class="o">:</span> %.<span class="n">o</span>                  <span class="c"># Preserve intermediate files
</span></span></span><span class="line"><span class="cl"><span class="nf">.SECONDARY</span><span class="o">:</span>                     <span class="c"># All intermediate files are secondary
</span></span></span><span class="line"><span class="cl"><span class="nf">.DELETE_ON_ERROR</span><span class="o">:</span>               <span class="c"># Delete target file if command errors
</span></span></span></code></pre></div><h3 id="tips-and-tricks">Tips and Tricks</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-makefile" data-lang="makefile"><span class="line"><span class="cl"><span class="nf">all</span><span class="o">:</span> <span class="k">$(</span><span class="nv">object</span><span class="k">)</span>                      <span class="c"># make finds dependencies then executes commands
</span></span></span><span class="line"><span class="cl">                                    <span class="c1"># doesn&#39;t have to compile to &#39;all&#39;</span>
</span></span><span class="line"><span class="cl"><span class="nf">$(object) </span><span class="o">:</span> ...
</span></span><span class="line"><span class="cl">    ...
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">gcc</span> <span class="err">-MM</span> <span class="err">hello.c</span>                     <span class="c"># Find header dependencies for hello.c
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">dev</span><span class="o">:</span> <span class="n">mymodule</span>.<span class="n">so</span>
</span></span><span class="line"><span class="cl">    @echo <span class="s2">&#34;Development build complete&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">test</span><span class="o">:</span> <span class="n">dev</span>                           <span class="c"># Set prerequisite tasks for multi-language development
</span></span></span><span class="line"><span class="cl">    <span class="k">$(</span>PYTHON<span class="k">)</span> -c <span class="s2">&#34;import mymodule; print(mymodule.hello())&#34;</span>
</span></span></code></pre></div><hr>
]]></content:encoded></item><item><title>JVM in short</title><link>https://www.parkerchenca.com/tech/jvm-in-short/</link><pubDate>Thu, 10 Sep 2026 11:22:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/jvm-in-short/</guid><description>Super Simplified JVM Notes</description><content:encoded><![CDATA[<h2 id="what-is-the-jvm">What is the JVM?</h2>
<ol>
<li>Java programs need the JVM to run.</li>
<li>Like .NET Framework.</li>
<li>Stands for <strong>Java Virtual Machine</strong>. Java can run on multiple platforms because JVMs are implemented for different systems. So, Java programs can run on any platform that has a JVM (Though JVM may be different).</li>
<li>It executes bytecode, which is translated from Java code.</li>
<li>Oh, and Kotlin code can also be compiled into bytecode.</li>
</ol>
<h2 id="what-are-jre-jdk-and-jar">What are JRE, JDK, and JAR?</h2>
<ol>
<li><strong>JRE</strong> (Java Runtime Environment) – It&rsquo;s what Java needs to run, includes the JVM.</li>
<li><strong>JDK</strong> (Java Development Kit) – The toolkit for Java developers (You need it to do developing things), and it includes the JRE. It also contains the <code>javac</code> compiler, which turns your code into bytecode.</li>
<li><strong>JAR</strong> (Java ARchive) – A zip file specifically for Java programs. If everything’s set up correctly, you can run it directly.</li>
</ol>
<h2 id="what-is-the-jvm-made-of">What is the JVM made of?</h2>
<ol>
<li><strong>Class Loader Subsystem</strong> – Finds your classes.</li>
<li><strong>Runtime Data Area</strong> – Contains the native method stack, Java method stack, method area, PC Registers, and heap.
<ol>
<li>Native Method Stack – For calling code in other languages (mainly C++).</li>
<li>Java Method Stack – For storing Java function call stacks.</li>
<li>PC Registers – Tells the interpreter where to go next. Fact: It’s the only area that won’t throw an <strong>OutOfMemoryError</strong>.</li>
<li>Method Area – Holds class-related info. It’s shared between threads.</li>
<li>Heap – Just the heap, shared between threads.</li>
<li>Anything not explicitly mentioned is thread-private.</li>
</ol>
</li>
<li><strong>Execution Engine</strong> – Interpreter, JIT (Just-In-Time compiler), and GC (Garbage Collector).</li>
<li><strong>Native Method Library</strong>.</li>
</ol>
<h2 id="class-loader-subsystem">Class Loader Subsystem?</h2>
<ol>
<li><strong>MyClass.java</strong> -&gt; Loading (find the class) -&gt; Linking -&gt; Verify, Prepare, Resolve -&gt; Initialization.
<ol>
<li><strong>Verify</strong> – Did you write your class correctly?</li>
<li><strong>Prepare</strong> – Allocates memory for <code>static</code> variables and sets them to default.</li>
<li><strong>Resolve</strong> – Turns symbolic references (names) into direct references (addresses).</li>
</ol>
</li>
</ol>
<h2 id="loading-class-loaders">Loading: Class Loaders</h2>
<p>Everything’s an object in Java, even the classes themselves are loaded by class loader objects.</p>
<ol>
<li><strong>BootStrapClassLoader</strong> – The default loader, it looks in the <code>jre/Lib</code> directory.</li>
<li><strong>ExtClassLoader</strong> – Inherits from <code>BootStrapClassLoader</code> and <code>ClassLoader</code>, looks in <code>jre/Lib/ext</code>.</li>
<li><strong>AppClassLoader</strong> – Inherits from <code>ExtClassLoader</code> and <code>ClassLoader</code>, looks in the working directory.
<ul>
<li>Thanks to the delegation, it will always check the parent loader first, preventing duplicate class loads. If the parent finds a class, it won’t look further.</li>
<li>Can specify the classpath using <code>classpath</code> in the command line.</li>
<li><strong>Tomcat</strong> has its own class loader, which extends <code>ClassLoader</code>.</li>
</ul>
</li>
</ol>
<h2 id="method-area">Method Area?</h2>
<p>Holds the constant pool, method info, and class info.</p>
<h2 id="java-method-stack-jvm-language-stack">Java Method Stack (JVM Language Stack)?</h2>
<p>It has a <strong>local variable table</strong>, <strong>operand stack</strong>, <strong>dynamic linking</strong>, and <strong>method return addresses</strong>. The native method stack is similar but handles methods from other languages.</p>
<ul>
<li><strong>Local Variable Table</strong> – Stores variable names and values.</li>
<li><strong>Operand Stack</strong> – Fetches variables from the local variable table for computation. The value is removed from the variable table when it&rsquo;s being computed.</li>
</ul>
<h2 id="heap">Heap?</h2>
<ul>
<li>Objects live here. Generally, it’s about <code>physical memory / 64</code> in size, maxing out at <code>physical memory / 4</code>.</li>
<li>It’s divided into the <strong>young generation</strong> and the <strong>old generation</strong>, with a default size ratio of 1:2.</li>
<li>The young generation is further divided into the <strong>eden</strong>, <strong>S1</strong>, and <strong>S2</strong> spaces, with a default ratio of 8:1:1.</li>
<li>New objects go into the <strong>eden</strong>. When eden fills up, it triggers a <strong>young/minor GC</strong>. Surviving objects are moved to either <strong>S1</strong> or <strong>S2</strong>.
<ul>
<li>During each GC, survivors in S1 or S2 also get checked. Survivors of the survivor spaces “jump” between <strong>S1</strong> and <strong>S2</strong>.</li>
<li>If an object survives long enough, it moves to the <strong>old generation</strong>.</li>
<li>If an object is too large to fit into eden or S1/S2, it goes directly to the <strong>old generation</strong>.</li>
</ul>
</li>
<li>The old generation is handled by another GC, like <strong>major GC</strong> or <strong>Full GC</strong>.
<ul>
<li><strong>Major GC</strong> is mostly and only done by <strong>CMS method (See below)</strong>, while Full GC will clean the old generation along with everything else.</li>
</ul>
</li>
</ul>
<h2 id="gc">GC?</h2>
<h3 id="how-to-find-garbage">How to Find Garbage?</h3>
<ul>
<li><strong>Reference counting</strong> – Track the number of references to an object. But this can’t handle circular references.</li>
<li><strong>Reachability analysis</strong> – Defines several <strong>GC roots</strong> and traverses the objects from those roots like a tree. Anything unreachable is considered garbage.
<ul>
<li>Possible GC roots include things like currently running methods, constants, and static variables in the method area.</li>
</ul>
</li>
</ul>
<h3 id="how-to-reclaim-garbage">How to Reclaim Garbage?</h3>
<ol>
<li><strong>Mark-Sweep</strong> – Marks the garbage and deletes it.
<ul>
<li>This can lead to memory fragmentation, where there’s not enough contiguous space to allocate new objects.</li>
</ul>
</li>
<li><strong>Copy</strong> – Copies live objects elsewhere, then deletes the whole old memory space.
<ul>
<li>This requires a backup memory space of the same size.</li>
<li>It moves objects, which can take some time.</li>
</ul>
</li>
<li><strong>Mark-Compact</strong> – Marks the garbage and deletes it, then compacts the remaining live objects.
<ul>
<li>It’s the slowest of the three algorithms.</li>
</ul>
</li>
</ol>
<h3 id="how-to-do-it-better">How to Do It Better?</h3>
<p>Generational collection:</p>
<ol>
<li>Objects with short lifetimes (in the young generation) are best handled by the copy algorithm because you can get rid of a lot of garbage quickly.</li>
<li>Long-living objects (in the old generation) generally don&rsquo;t use the copy algorithm and instead rely on other algorithms based on needs.</li>
</ol>
<h2 id="common-gc-algorithms">Common GC Algorithms</h2>
<ol>
<li><strong>Serial GC</strong> – An old algorithm. It pauses work threads, starts a new thread to perform GC, and uses the mark-sweep and mark-compact algorithms.</li>
<li><strong>ParNew GC</strong> – A multithreaded version of Serial GC.</li>
<li><strong>CMS</strong> (<strong>Concurrent Mark-Sweep Garbage Collector</strong>) – Used for the old generation, it uses the mark-sweep method. It minimizes pauses by using initial marking but requires an extra re-marking step to ensure accuracy. <strong>Most of its work happens in parallel with application threads.</strong> It&rsquo;s now considered outdated.</li>
<li><strong>Parallel GC</strong> – Replaces the Serial algorithm and can dynamically adjust memory allocation. It’s the default in JDK 8.</li>
<li><strong>Newer GCs, mainly Full GC</strong>:
<ol>
<li><strong>G1</strong> (Garbage First) – A region-based algorithm that divides memory into 2048 regions. Its strength is that it offers controllable latency. It’s the default in JDK 9. It has final marking and evacuation steps, where most of the time is spent. With the help of initial marking, <strong>the rest of the process happens in parallel with application threads</strong>.</li>
<li><strong>ZGC</strong> – A complex paging-based algorithm. Its unique feature is short STW (Stop-the-World) times, which don’t increase with heap size.</li>
<li><strong>For the new generation GC</strong>, the algorithms are not so straightforward, so you might want to dive deeper into that yourself.</li>
</ol>
</li>
</ol>
]]></content:encoded></item><item><title>Two Ways to Reverse a Singly Linked List</title><link>https://www.parkerchenca.com/tech/two-ways-to-reverse-a-singly-linked-list/</link><pubDate>Thu, 10 Sep 2026 11:20:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/two-ways-to-reverse-a-singly-linked-list/</guid><description>&lt;h2 id="0-structure-of-a-singly-linked-list"&gt;0. Structure of a Singly Linked List&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ListNode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&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="nb"&gt;next&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;next&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;NULL&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="1-move-pointers"&gt;1. Move pointers&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;reverseList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ListNode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ListNode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;prev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;curr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;head&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;curr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;temp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;curr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt; &lt;span class="c1"&gt;# Save next node&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;curr&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prev&lt;/span&gt; &lt;span class="c1"&gt;# Reverse the pointer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;prev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;curr&lt;/span&gt; &lt;span class="c1"&gt;# Move prev forward&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;curr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt; &lt;span class="c1"&gt;# Move curr forward&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;prev&lt;/span&gt; &lt;span class="c1"&gt;# New head of the reversed list&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;0:
1 -&amp;gt; None 2 -&amp;gt; 3 -&amp;gt; 4 -&amp;gt; 5 -&amp;gt; NULL&lt;/p&gt;
&lt;p&gt;1:
2 -&amp;gt; 1 -&amp;gt; None 3 -&amp;gt; 4 -&amp;gt; 5 -&amp;gt; NULL&lt;/p&gt;</description><content:encoded><![CDATA[<h2 id="0-structure-of-a-singly-linked-list">0. Structure of a Singly Linked List</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">ListNode</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">val</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="nb">next</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">val</span> <span class="o">=</span> <span class="n">val</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">next</span> <span class="o">=</span> <span class="nb">next</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">//</span> <span class="mi">1</span> <span class="o">-&gt;</span> <span class="mi">2</span> <span class="o">-&gt;</span> <span class="mi">3</span> <span class="o">-&gt;</span> <span class="mi">4</span> <span class="o">-&gt;</span> <span class="mi">5</span> <span class="o">-&gt;</span> <span class="n">NULL</span>
</span></span></code></pre></div><h2 id="1-move-pointers">1. Move pointers</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">reverseList</span><span class="p">(</span><span class="n">head</span><span class="p">:</span> <span class="n">ListNode</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ListNode</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">prev</span> <span class="o">=</span> <span class="kc">None</span>
</span></span><span class="line"><span class="cl">    <span class="n">curr</span> <span class="o">=</span> <span class="n">head</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">while</span> <span class="n">curr</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">temp</span> <span class="o">=</span> <span class="n">curr</span><span class="o">.</span><span class="n">next</span>    <span class="c1"># Save next node</span>
</span></span><span class="line"><span class="cl">        <span class="n">curr</span><span class="o">.</span><span class="n">next</span> <span class="o">=</span> <span class="n">prev</span>    <span class="c1"># Reverse the pointer</span>
</span></span><span class="line"><span class="cl">        <span class="n">prev</span> <span class="o">=</span> <span class="n">curr</span>         <span class="c1"># Move prev forward</span>
</span></span><span class="line"><span class="cl">        <span class="n">curr</span> <span class="o">=</span> <span class="n">temp</span>         <span class="c1"># Move curr forward</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">prev</span>  <span class="c1"># New head of the reversed list</span>
</span></span></code></pre></div><p>0:
1 -&gt; None  2 -&gt; 3 -&gt; 4 -&gt; 5 -&gt; NULL</p>
<p>1:
2 -&gt; 1 -&gt; None     3 -&gt; 4 -&gt; 5 -&gt; NULL</p>
<p>2:
3 -&gt; 2 -&gt; 1 -&gt; None     4 -&gt; 5 -&gt; NULL</p>
<p>3:
4 -&gt; 3 -&gt; 2 -&gt; 1 -&gt; None     5 -&gt; NULL</p>
<p>4:
5 -&gt; 4 -&gt; 3 -&gt; 2 -&gt; 1 -&gt; None</p>
<hr>
<h2 id="2-head-insertion">2. Head Insertion</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">reverseList</span><span class="p">(</span><span class="n">head</span><span class="p">:</span> <span class="n">ListNode</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ListNode</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">prev</span> <span class="o">=</span> <span class="n">ListNode</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">prev</span><span class="o">.</span><span class="n">next</span> <span class="o">=</span> <span class="n">head</span>
</span></span><span class="line"><span class="cl">    <span class="n">curr</span> <span class="o">=</span> <span class="n">prev</span><span class="o">.</span><span class="n">next</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">while</span> <span class="n">curr</span><span class="o">.</span><span class="n">next</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">temp</span> <span class="o">=</span> <span class="n">curr</span><span class="o">.</span><span class="n">next</span>
</span></span><span class="line"><span class="cl">        <span class="n">curr</span><span class="o">.</span><span class="n">next</span> <span class="o">=</span> <span class="n">temp</span><span class="o">.</span><span class="n">next</span>
</span></span><span class="line"><span class="cl">        <span class="n">temp</span><span class="o">.</span><span class="n">next</span> <span class="o">=</span> <span class="n">prev</span><span class="o">.</span><span class="n">next</span>
</span></span><span class="line"><span class="cl">        <span class="n">prev</span><span class="o">.</span><span class="n">next</span> <span class="o">=</span> <span class="n">temp</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">prev</span><span class="o">.</span><span class="n">next</span>
</span></span></code></pre></div><p>0:
1 -&gt; 2 -&gt; 3 -&gt; 4 -&gt; 5 -&gt; NULL</p>
<p>1:
<strong>2 -&gt; 1</strong> -&gt; 3 -&gt; 4 -&gt; 5 -&gt; NULL</p>
<p>2:
<strong>3 -&gt; 2 -&gt; 1</strong> -&gt; 4 -&gt; 5 -&gt; NULL</p>
<p>3:
<strong>4 -&gt; 3 -&gt; 2 -&gt; 1</strong> -&gt; 5 -&gt; NULL</p>
<p>4:
<strong>5 -&gt; 4 -&gt; 3 -&gt; 2 -&gt; 1</strong> -&gt; NULL</p>
]]></content:encoded></item><item><title>Rust Notes 4</title><link>https://www.parkerchenca.com/tech/rust-notes-4/</link><pubDate>Thu, 10 Sep 2026 11:19:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/rust-notes-4/</guid><description>Range</description><content:encoded><![CDATA[<h2 id="range">Range</h2>
<p>Rather than using C style loop, in Rust, we use ..= to indicate a range:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">for</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="mi">1</span><span class="o">..=</span><span class="mi">5</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">&#34;</span><span class="si">{}</span><span class="s">&#34;</span><span class="p">,</span><span class="n">i</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>Output:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="mi">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="mi">2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="mi">3</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="mi">4</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="mi">5</span><span class="w">
</span></span></span></code></pre></div><p>Sequences are only allowed for numeric or character types because they can be consecutive.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">for</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="sc">&#39;a&#39;</span><span class="o">..=</span><span class="sc">&#39;z&#39;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">&#34;</span><span class="si">{}</span><span class="s">&#34;</span><span class="p">,</span><span class="n">i</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><h3 id="char">Char</h3>
<p>Use <code>''</code> . <code>&quot;&quot;</code> is for the string</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="sc">&#39;z&#39;</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">z</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="sc">&#39;ℤ&#39;</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">cat</span><span class="o">=</span><span class="w"> </span><span class="sc">&#39;😻&#39;</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>Accept <code>Unicode</code>, occupy 4 bytes.</p>
<h3 id="bool">Bool</h3>
<p>Only 1 byte.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">t</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">true</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">f</span>: <span class="kt">bool</span> <span class="o">=</span><span class="w"> </span><span class="kc">false</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><h3 id="unit-type">Unit type</h3>
<p>Literally, it is <code>()</code>.</p>
<p>Yes, the unit type is <code>()</code>, and the value of this type is also, and only <code>()</code>.</p>
<p>It&rsquo;s similar to <code>void</code> in other languages.</p>
<p>Sometimes, you may come across code like <code>Result&lt;(), String&gt;</code>. This is an example of <strong>generic types</strong> in Rust. If you&rsquo;re familiar with C++ generic types, you can figure out that we pass 2 types into the <code>Result</code>, regardless of what the <code>Result</code> actually is.</p>
]]></content:encoded></item><item><title>Rust Notes 3</title><link>https://www.parkerchenca.com/tech/rust-notes-3/</link><pubDate>Thu, 10 Sep 2026 11:16:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/rust-notes-3/</guid><description>Basic types 1</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
In the end, all data types in Rust come from these primitive types.</p>
</blockquote>
<h2 id="basic-types">Basic types</h2>
<ul>
<li>Every value in Rust has a specific data type</li>
<li>In general, these can be divided into two categories: <strong>scalar</strong> types and <strong>compound</strong> types</li>
<li>Scalar types include:
<ul>
<li><strong>Numbers</strong>: Signed integers (<code>i8</code>, <code>i16</code>, <code>i32</code>, <code>i64</code>, <code>isize</code>), unsigned integers (<code>u8</code>, <code>u16</code>, <code>u32</code>, <code>u64</code>, <code>usize</code>), floating-point numbers (<code>f32</code>, <code>f64</code>)
<ul>
<li>The <code>isize</code> and <code>usize</code> types depend on the architecture of the computer the program is running on: if the CPU is 32-bit, these types are 32-bit; similarly, if the CPU is 64-bit, they are</li>
<li>Rust&rsquo;s <strong>default</strong> integer type is <code>i32</code></li>
<li>Can overflow, and Rust does not check for this by default. If you encounter incorrect values, make sure to check the type of your numbers.</li>
</ul>
</li>
<li><strong>Strings</strong>: String literals and string slices</li>
<li><strong>Booleans</strong>: <code>true</code> and <code>false</code></li>
<li><strong>Characters</strong>: Representing a single Unicode character, stored as 4 bytes</li>
<li><strong>Unit type</strong>: Represented by <code>()</code>, with its only value also being <code>()</code></li>
</ul>
</li>
</ul>
<hr>
<h3 id="be-careful-with-floats">Be Careful with <code>float</code>s</h3>
<p>See this example:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="fm">assert!</span><span class="p">(</span><span class="mf">0.1</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">0.2</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mf">0.3</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>You might think this would return <code>true</code> , but the truth is, the program will panic and quit.</p>
<ul>
<li>Due to binary precision issues, <code>0.1 + 0.2</code> is not exactly equal to <code>0.3</code></li>
<li>You can consider using this approach: <code>(0.1_f64 + 0.2 - 0.3).abs() &lt; 0.00001</code></li>
</ul>
<hr>
<h3 id="nan">NaN</h3>
<ul>
<li><code>-42.1.sqrt()</code> will produce <code>NaN</code></li>
<li>Any operation involving <code>NaN</code> will return <code>NaN</code></li>
<li>Comparing <code>NaN</code> will cause the code to panic and crash</li>
<li>Use <code>is_nan()</code> to determine if a value is <code>NaN</code></li>
</ul>
<hr>
<h3 id="use"><strong>Use <code>as</code> for Type Conversion</strong></h3>
<p>In Rust, you can use <code>as</code> to convert one type to another.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">x</span>: <span class="kt">i32</span> <span class="o">=</span><span class="w"> </span><span class="mi">10</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">y</span>: <span class="kt">f64</span> <span class="o">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="kt">f64</span><span class="p">;</span><span class="w"> </span><span class="c1">// Convert i32 to f64
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">&#34;x as f64 is: </span><span class="si">{}</span><span class="s">&#34;</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>]]></content:encoded></item><item><title>Rust Notes 2</title><link>https://www.parkerchenca.com/tech/rust-notes-2/</link><pubDate>Thu, 10 Sep 2026 11:15:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/rust-notes-2/</guid><description>Basic syntax: variable and function</description><content:encoded><![CDATA[<h2 id="syntax-of-rust">Syntax of Rust</h2>
<p>Don’t worry, this will be very easy at the beginning. (Really?)</p>
<hr>
<h3 id="function-goes-first">Function goes first</h3>
<ul>
<li>Similar to C and C++, there must be a <code>main</code> function as the entry point of the program.</li>
<li>Use <code>fn</code> to declare a function, so concise.</li>
<li>Use <code>()</code> for receiving parameters, and <code>{}</code> for the actual logic inside the function.</li>
<li>Remember to use <code>;</code> to end a statement. As I said, it’s similar to C and C++.</li>
<li>Example:</li>
</ul>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span>-&gt; <span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">&#34;Hello, world!&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// &#34;ln&#34; means print with a new line after the content
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// What is &#34;!&#34;? Well, it means this function is actually a macro
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// For now, let&#39;s just use it as is
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// You don&#39;t need to learn everything to start using Rust. Heart.
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><p>A complete structure of function head in Rust should be:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="n">keyword</span><span class="w"> </span><span class="n">name</span><span class="p">(</span><span class="n">parameter</span>: <span class="nc">type</span><span class="w"> </span><span class="p">)</span><span class="w"> </span>-&gt; <span class="p">[</span><span class="k">return</span><span class="w"> </span><span class="k">type</span><span class="p">]</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">body</span><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">fn</span>      <span class="nf">myFunction</span><span class="p">(</span><span class="n">para</span><span class="w"> </span>: <span class="kt">i32</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">i32</span> <span class="p">{</span><span class="w"> </span><span class="o">..</span><span class="p">.</span><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><hr>
<h3 id="define-variables">Define variables</h3>
<ul>
<li>You <strong>must</strong> use <code>let</code> to create a variable.
<ul>
<li><code>let myVar = 3;</code></li>
<li><code>let myVar: u32 = 3;</code> → Explicitly specifies the type of the variable <code>myVar</code> as <code>u32</code>. <code>u32</code> is a 32-bit unsigned integer type in Rust.</li>
<li><code>let mut myVar = 3;</code> → Creates a <strong>mutable</strong> variable.</li>
</ul>
</li>
<li>What? Mutable?
<ul>
<li>Variables in Rust are <strong>immutable by default</strong>.(Its value is determined after compilation.)</li>
<li>It&rsquo;s important to understand that in Rust, <code>some_variable = some_value</code> is not just <strong>assigning</strong> a value, but rather <strong>binding</strong> the value to the variable.</li>
<li>This topic is related to Rust’s Ownership feature, which we will discuss in the next post.</li>
<li>Here&rsquo;s an example:</li>
</ul>
</li>
</ul>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">myVar</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">5</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">myVar</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">6</span><span class="p">;</span><span class="w"> </span><span class="c1">// Error
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">myMutVar</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">5</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">myMutVar</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">6</span><span class="p">;</span><span class="w"> </span><span class="c1">// Pass
</span></span></span></code></pre></div><ul>
<li>If you understand that variables are bound to values, it becomes easier to grasp <strong>variable destructuring</strong>:
<ul>
<li>Basically, destructuring means extracting values from patterns.</li>
</ul>
</li>
</ul>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">b</span><span class="p">)</span>: <span class="p">(</span><span class="kt">bool</span><span class="p">,</span><span class="kt">bool</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="kc">false</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">&#34;a = </span><span class="si">{:?}</span><span class="s">, b = </span><span class="si">{:?}</span><span class="s">&#34;</span><span class="p">,</span><span class="w"> </span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// You can treat the {} as a placeholder for a or b
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// :? is for &#34;formatting&#34; output and &#34;debugging&#34; output
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Whatever, it should print the value of a and b
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">b</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">true</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="fm">assert_eq!</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="w"> </span><span class="n">b</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><ul>
<li>You can also use <code>const</code> to define a constant value:
<ul>
<li><code>const MY_CONST_VALUE: i32 = 5;</code></li>
<li>Constants must always have a type annotation, unlike regular variables.</li>
</ul>
</li>
</ul>
<hr>
<h4 id="statement-and-expression"><strong>Statement and expression</strong></h4>
<ul>
<li>In short:</li>
</ul>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">add_with_extra</span><span class="p">(</span><span class="n">x</span>: <span class="kt">i32</span><span class="p">,</span><span class="w"> </span><span class="n">y</span>: <span class="kt">i32</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">i32</span>  <span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w"> </span><span class="c1">// Statement
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">5</span><span class="p">;</span><span class="w"> </span><span class="c1">// Statement
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">x</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="c1">// Expression. Hey! Attention here! No &#34;;&#34; after the sentence!
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// Also expression is expected to &#34;return&#34; something
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// So we can avoid to write &#34;return&#34; in the end of our fn
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// In other word, statament CANNOT return a value
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></div><ul>
<li>Interesting facts:
<ul>
<li>In <code>let x = 1;</code>
<ul>
<li><code>x</code> is an expression</li>
<li><code>1</code> is an expression</li>
<li><code>let x = 1;</code> is a statement</li>
<li>Bound</li>
</ul>
</li>
</ul>
</li>
<li>Lastly, if an expression doesn’t return anything, it returns <code>()</code>
<ul>
<li><code>()</code> is both a type and a value, and the value is <code>()</code>.</li>
<li>You can treat the <code>()</code> as a <code>()</code>, yes, that is it.</li>
</ul>
</li>
</ul>
]]></content:encoded></item><item><title>Rust Notes 1</title><link>https://www.parkerchenca.com/tech/rust-notes-1/</link><pubDate>Thu, 10 Sep 2026 11:14:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/rust-notes-1/</guid><description>Hello world!</description><content:encoded><![CDATA[<h2 id="about-these-notes">About these notes</h2>
<p>These Rust notes are just a collection of my learning records. Since I&rsquo;m a beginner in Rust, these notes are more like quick references or supplements, rather than a comprehensive Rust tutorial. No matter what, I hope you can still find parts that are useful to you.</p>
<hr>
<h3 id="why-rust">Why rust？</h3>
<p>Rust&rsquo;s advantages include memory safety, high performance, and high productivity. To me, Rust appears to be one of the best implementations of C++. If you don&rsquo;t get into deeper topics and only use prepared libraries, Rust&rsquo;s syntax is simple and clear. Its built-in compiler cautions are also quite informative, which significantly decreases the amount of thinking required on developers.</p>
<p>However, Rust has been criticized for being &ldquo;too safe.&rdquo; If you want to dig deeper and truly utilize Rust, you&rsquo;ll have to deal with its complex and tedious safety mechanisms. A true dilemma exists: &ldquo;Why not use the more flexible C++, or Python, which offers quicker speed in development and a more strong ecosystem?&rdquo;</p>
<p>In my opinion, Rust is a &ldquo;balanced&rdquo; choice that addresses some shortcomings of mainstream languages. It is safer than C++ and performs better than Python. However, Rust has obvious drawbacks including an extremely high learning and development cost (which may be more difficult than learning C++). However, Rust is clearly a popular technology right now, and its ecosystem is rapidly expanding. Learning a challenging new language is never a terrible idea.</p>
<hr>
<h3 id="environment-prep">Environment prep</h3>
<ol>
<li>Follow the instructions at <a href="https://www.rust-lang.org/learn/get-started">https://www.rust-lang.org/learn/get-started</a> to install <strong>Rust</strong>.</li>
<li>Install VS Code.</li>
<li>Install the <strong>rust-analyzer</strong> extension in VS Code.</li>
<li>Well done! You’re now ready to write your first Rust program.</li>
</ol>
<p>Use Google or AI tools to help you do these tasks, you will deal with Google and AI all the time when you’re learning something new.</p>
<hr>
<h3 id="hello-world">Hello world</h3>
<ol>
<li>In VS Code, open a new folder.</li>
<li>Press `Ctrl + `` to open a new terminal, or you can follow the top menu tabs: &ldquo;Terminal&rdquo; -&gt; &ldquo;New Terminal&rdquo;.</li>
<li>Enter <code>cargo new helloworld</code> to create a new project named <code>helloworld</code>.
<ol>
<li><code>cargo</code> is like the <code>pip</code> in Python; it manages packages (libraries) in Rust.</li>
</ol>
</li>
<li>Go into the <code>src</code> folder, and you will find the <code>main.rs</code> file.</li>
<li>Enter <code>cargo run</code> in the terminal to directly run … oops! An error occurs.
<ol>
<li>You need to first navigate into the <code>helloworld</code> directory because that’s the project’s working directory.</li>
<li>Use <code>cd helloworld</code>, or open the folder again in VS Code, and then create a new terminal.</li>
<li>Enter <code>cargo run</code>.</li>
<li>Congratulations! You&rsquo;ve run your first Rust program!</li>
</ol>
</li>
</ol>
]]></content:encoded></item><item><title>Window Functions in SQL</title><link>https://www.parkerchenca.com/tech/window-functions-in-sql/</link><pubDate>Thu, 10 Sep 2026 11:13:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/window-functions-in-sql/</guid><description>Apply Aggregate Functions to Specific Data</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong></p>
<p>Boss: &ldquo;I need the average sales for 7 days.&rdquo;</p>
<p>Me: &ldquo;Sure! Which 7 days?&rdquo;</p>
<p>Boss: &ldquo;All the 7 days!&rdquo;</p>
<p>Me: &ldquo;Su…Sure…?&rdquo;</p>
</blockquote>
<h2 id="-window-functions">🖋️ Window Functions</h2>
<p>Window functions are generally applied after aggregate functions like <code>MAX()</code>, <code>MIN()</code>, <code>AVG()</code> to perform calculations <strong>across</strong> a set of table rows(days before, days after) that are related to the current row(current day).</p>
<h4 id="example-table-1-employees">Example Table 1: <code>employees</code></h4>
<table>
	<thead>
			<tr>
					<th>employee_id</th>
					<th>department_id</th>
					<th>salary</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>1</td>
					<td>101</td>
					<td>5000</td>
			</tr>
			<tr>
					<td>2</td>
					<td>101</td>
					<td>6000</td>
			</tr>
			<tr>
					<td>3</td>
					<td>101</td>
					<td>5500</td>
			</tr>
			<tr>
					<td>4</td>
					<td>102</td>
					<td>7000</td>
			</tr>
			<tr>
					<td>5</td>
					<td>102</td>
					<td>7200</td>
			</tr>
			<tr>
					<td>6</td>
					<td>102</td>
					<td>6800</td>
			</tr>
	</tbody>
</table>
<h4 id="example-1-over-without-partitioning">Example 1: <code>OVER()</code> Without Partitioning</h4>
<p>Calculate the average salary for all employees:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">employee_id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">department_id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">salary</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">AVG</span><span class="p">(</span><span class="n">salary</span><span class="p">)</span><span class="w"> </span><span class="n">OVER</span><span class="p">()</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">avg_salary_all_departments</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">FROM</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">employees</span><span class="p">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Result:</strong></p>
<table>
	<thead>
			<tr>
					<th>employee_id</th>
					<th>department_id</th>
					<th>salary</th>
					<th><strong>avg_salary_all_departments</strong></th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>1</td>
					<td>101</td>
					<td>5000</td>
					<td>6250</td>
			</tr>
			<tr>
					<td>2</td>
					<td>101</td>
					<td>6000</td>
					<td>6250</td>
			</tr>
			<tr>
					<td>3</td>
					<td>101</td>
					<td>5500</td>
					<td>6250</td>
			</tr>
			<tr>
					<td>4</td>
					<td>102</td>
					<td>7000</td>
					<td>6250</td>
			</tr>
			<tr>
					<td>5</td>
					<td>102</td>
					<td>7200</td>
					<td>6250</td>
			</tr>
			<tr>
					<td>6</td>
					<td>102</td>
					<td>6800</td>
					<td>6250</td>
			</tr>
	</tbody>
</table>
<h4 id="example-2-partition-by">Example 2: <code>PARTITION BY</code></h4>
<p>Calculate the average salary <strong>per</strong> department:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">employee_id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">department_id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">salary</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">AVG</span><span class="p">(</span><span class="n">salary</span><span class="p">)</span><span class="w"> </span><span class="n">OVER</span><span class="p">(</span><span class="n">PARTITION</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">department_id</span><span class="p">)</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">avg_salary_per_department</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">FROM</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">employees</span><span class="p">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Result:</strong></p>
<table>
	<thead>
			<tr>
					<th>employee_id</th>
					<th>department_id</th>
					<th>salary</th>
					<th><strong>avg_salary_per_department</strong></th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>1</td>
					<td>101</td>
					<td>5000</td>
					<td>5500</td>
			</tr>
			<tr>
					<td>2</td>
					<td>101</td>
					<td>6000</td>
					<td>5500</td>
			</tr>
			<tr>
					<td>3</td>
					<td>101</td>
					<td>5500</td>
					<td>5500</td>
			</tr>
			<tr>
					<td>4</td>
					<td>102</td>
					<td>7000</td>
					<td>7000</td>
			</tr>
			<tr>
					<td>5</td>
					<td>102</td>
					<td>7200</td>
					<td>7000</td>
			</tr>
			<tr>
					<td>6</td>
					<td>102</td>
					<td>6800</td>
					<td>7000</td>
			</tr>
	</tbody>
</table>
<h4 id="example-3-order-by-with-ranking">Example 3: <code>ORDER BY</code> with Ranking</h4>
<p>Rank employees <strong>by</strong> salary <strong>within</strong> their departments:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">employee_id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">department_id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">salary</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">RANK</span><span class="p">()</span><span class="w"> </span><span class="n">OVER</span><span class="p">(</span><span class="n">PARTITION</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="o">**</span><span class="n">department_id</span><span class="o">**</span><span class="w"> </span><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="o">**</span><span class="n">salary</span><span class="o">**</span><span class="w"> </span><span class="k">DESC</span><span class="p">)</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="o">**</span><span class="n">salary_rank</span><span class="o">**</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">FROM</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">employees</span><span class="p">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Result:</strong></p>
<table>
	<thead>
			<tr>
					<th>employee_id</th>
					<th><strong>department_id</strong></th>
					<th><strong>salary</strong></th>
					<th><strong>salary_rank</strong></th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>2</td>
					<td>101</td>
					<td>6000</td>
					<td>1</td>
			</tr>
			<tr>
					<td>3</td>
					<td>101</td>
					<td>5500</td>
					<td>2</td>
			</tr>
			<tr>
					<td>1</td>
					<td>101</td>
					<td>5000</td>
					<td>3</td>
			</tr>
			<tr>
					<td>5</td>
					<td>102</td>
					<td>7200</td>
					<td>1</td>
			</tr>
			<tr>
					<td>4</td>
					<td>102</td>
					<td>7000</td>
					<td>2</td>
			</tr>
			<tr>
					<td>6</td>
					<td>102</td>
					<td>6800</td>
					<td>3</td>
			</tr>
	</tbody>
</table>
<hr>
<h4 id="example-table-2-orders">Example Table 2: <code>orders</code></h4>
<table>
	<thead>
			<tr>
					<th>order_id</th>
					<th>order_date</th>
					<th>order_total</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>1</td>
					<td>2023-01-01</td>
					<td>100</td>
			</tr>
			<tr>
					<td>2</td>
					<td>2023-01-03</td>
					<td>200</td>
			</tr>
			<tr>
					<td>3</td>
					<td>2023-01-05</td>
					<td>150</td>
			</tr>
			<tr>
					<td>4</td>
					<td>2023-01-07</td>
					<td>250</td>
			</tr>
			<tr>
					<td>5</td>
					<td>2023-01-09</td>
					<td>300</td>
			</tr>
	</tbody>
</table>
<h4 id="example-4-range-with-date-intervals">Example 4: <code>RANGE</code> with Date Intervals</h4>
<p>Sum the total orders in the last 7 days for <strong>each row</strong>: (INTERVAL 6 because included CURRENT ROW)</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">order_id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">order_date</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">order_total</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">SUM</span><span class="p">(</span><span class="n">order_total</span><span class="p">)</span><span class="w"> </span><span class="n">OVER</span><span class="p">(</span><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">order_date</span><span class="w"> </span><span class="n">RANGE</span><span class="w"> </span><span class="k">BETWEEN</span><span class="w"> </span><span class="nb">INTERVAL</span><span class="w"> </span><span class="s1">&#39;6&#39;</span><span class="w"> </span><span class="k">DAY</span><span class="w"> </span><span class="n">PRECEDING</span><span class="w"> </span><span class="k">AND</span><span class="w"> </span><span class="k">CURRENT</span><span class="w"> </span><span class="k">ROW</span><span class="p">)</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">sum_last_7_days</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">FROM</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">orders</span><span class="p">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Result:</strong></p>
<table>
	<thead>
			<tr>
					<th>order_id</th>
					<th>order_date</th>
					<th>order_total</th>
					<th>sum_last_7_days</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>1</td>
					<td>2023-01-01</td>
					<td>100</td>
					<td>100</td>
			</tr>
			<tr>
					<td>2</td>
					<td>2023-01-03</td>
					<td>200</td>
					<td>300</td>
			</tr>
			<tr>
					<td>3</td>
					<td>2023-01-05</td>
					<td>150</td>
					<td>450</td>
			</tr>
			<tr>
					<td>4</td>
					<td>2023-01-07</td>
					<td>250</td>
					<td>700</td>
			</tr>
			<tr>
					<td>5</td>
					<td>2023-01-09</td>
					<td>300</td>
					<td>950</td>
			</tr>
	</tbody>
</table>
<h4 id="example-5-rows-between-preceding-and-following">Example 5: <code>ROWS</code> Between Preceding and Following</h4>
<p>Calculate the sum of order totals for the current row and the 2 preceding rows:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">order_id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">order_date</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">order_total</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">SUM</span><span class="p">(</span><span class="n">order_total</span><span class="p">)</span><span class="w"> </span><span class="n">OVER</span><span class="p">(</span><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">order_date</span><span class="w"> </span><span class="k">ROWS</span><span class="w"> </span><span class="k">BETWEEN</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="n">PRECEDING</span><span class="w"> </span><span class="k">AND</span><span class="w"> </span><span class="k">CURRENT</span><span class="w"> </span><span class="k">ROW</span><span class="p">)</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">sum_last_3_orders</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">FROM</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">orders</span><span class="p">;</span><span class="w">
</span></span></span></code></pre></div><p><strong>Result:</strong></p>
<table>
	<thead>
			<tr>
					<th>order_id</th>
					<th>order_date</th>
					<th>order_total</th>
					<th>sum_last_3_orders</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>1</td>
					<td>2023-01-01</td>
					<td>100</td>
					<td>100</td>
			</tr>
			<tr>
					<td>2</td>
					<td>2023-01-03</td>
					<td>200</td>
					<td>300</td>
			</tr>
			<tr>
					<td>3</td>
					<td>2023-01-05</td>
					<td>150</td>
					<td>450</td>
			</tr>
			<tr>
					<td>4</td>
					<td>2023-01-07</td>
					<td>250</td>
					<td>600</td>
			</tr>
			<tr>
					<td>5</td>
					<td>2023-01-09</td>
					<td>300</td>
					<td>700</td>
			</tr>
	</tbody>
</table>
<hr>
<h4 id="references-sheet">References sheet</h4>
<p>After max()…</p>
<ul>
<li><strong>OVER(…)</strong>: Applied <strong>over</strong> &hellip;</li>
<li><strong>PARTITION BY</strong>: Used to <strong>divide by</strong> &hellip;</li>
<li><strong>ORDER BY</strong> [DESC]</li>
<li><strong>ROWS</strong> <code>[BETWEEN...AND]</code>
<ol>
<li><code>n PRECEDING</code></li>
<li><code>n FOLLOWING</code></li>
<li><code>CURRENT ROW</code></li>
<li><code>UNBOUNDED PRECEDING</code> All before</li>
<li><code>UNBOUNDED FOLLOWING</code> All after</li>
</ol>
</li>
<li><strong>RANGE</strong> <code>[BETWEEN...AND]</code>
<ol>
<li><code>INTERVAL 'n' DAY</code></li>
</ol>
</li>
</ul>
]]></content:encoded></item><item><title>CO-STAR Template for ChatGPT</title><link>https://www.parkerchenca.com/tech/co-star-template-for-chatgpt/</link><pubDate>Thu, 10 Sep 2026 11:11:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/co-star-template-for-chatgpt/</guid><description>Getting ChatGPT to Do Exactly What You Need</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
If you use ChatGPT frequently, you&rsquo;ve probably encountered situations where it provides off-topic answers. Since we can&rsquo;t modify the model, the better approach is to rely on accurate prompts and additional context.</p>
</blockquote>
<h2 id="-main">🖋️ Main</h2>
<h4 id="let-chatgpt-answer-your-questions-accurately"><strong>Let ChatGPT Answer Your Questions Accurately!</strong></h4>
<p>First, you need to let ChatGPT know some personal information about you and how it should respond to you.</p>
<ol>
<li>Click on your profile picture at the top right corner.</li>
<li>Select &ldquo;Customize ChatGPT.&rdquo;</li>
<li>Hover over the &ldquo;Custom Instructions&rdquo; question mark on the right and fill in the information as guided.</li>
<li>Use the specific CO-STAR template in a new session.</li>
<li>Interact with ChatGPT.</li>
</ol>
<hr>
<h4 id="co-star-template">CO-STAR Template</h4>
<p>The CO-STAR template is a structured method that can help you communicate more clearly and effectively with ChatGPT. By providing context, objectives, style, tone, audience, and response format, you can explain exactly what you need from ChatGPT, and get replies that correspond more closely with your requirements.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl"># CO-STAR Template
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">## Template Example
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"># Context
</span></span><span class="line"><span class="cl"># I am a university student majoring in computer science, writing a paper on the application of machine learning in financial analysis.
</span></span><span class="line"><span class="cl"># Objective
</span></span><span class="line"><span class="cl"># Please help me write a section about the advantages and challenges of machine learning in stock market prediction.
</span></span><span class="line"><span class="cl"># Style
</span></span><span class="line"><span class="cl"># The style should be academic, using formal and technical language.
</span></span><span class="line"><span class="cl"># Tone
</span></span><span class="line"><span class="cl"># The tone should be serious and professional, avoiding humor or overly casual expressions.
</span></span><span class="line"><span class="cl"># Audience
</span></span><span class="line"><span class="cl"># The target audience is researchers and professionals in finance and computer science who are familiar with the relevant terminology and concepts.
</span></span><span class="line"><span class="cl"># Response
</span></span><span class="line"><span class="cl"># Please provide the content in paragraph form, including clear arguments and supporting evidence.
</span></span></code></pre></div><p>You can simply copy and paste this template to use it! Or, here is a more detailed explanation:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">## Context
</span></span><span class="line"><span class="cl"># Provide relevant background information to help the model understand the current situation.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">## Objective
</span></span><span class="line"><span class="cl"># Clearly state your goal or the task you want ChatGPT to help you with.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">## Style
</span></span><span class="line"><span class="cl"># Specify the desired writing style, such as formal, informal, technical, etc.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">## Tone
</span></span><span class="line"><span class="cl"># Define the desired tone, such as persuasive, humorous, serious, etc.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">## Audience
</span></span><span class="line"><span class="cl"># Define the target audience so the model can adjust the complexity and terminology of its output.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">## Response
</span></span><span class="line"><span class="cl"># Specify the desired response format, such as a list, paragraph, or a specific data format.
</span></span></code></pre></div>]]></content:encoded></item><item><title>Tips for Better Google Searches</title><link>https://www.parkerchenca.com/tech/tips-for-better-google-searches/</link><pubDate>Thu, 10 Sep 2026 11:10:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/tips-for-better-google-searches/</guid><description>lmgtfy.(Let me google that for you)</description><content:encoded><![CDATA[<blockquote>
<p>💡 <strong>Prelude:</strong>
I collected some common advanced keywords for Google searching. These tips are generally applicable to most search engines.
You can also “search” on this page to find what you need.</p>
</blockquote>
<h3 id="exact-keywords">Exact Keywords</h3>
<p>Use <code>&quot;key words ...&quot;</code> (<strong>double quotes</strong>) to prevent keywords from being split up during the search.</p>
<hr>
<h3 id="exclude-keywords">Exclude Keywords</h3>
<p>Use <code>-</code> to exclude keywords.</p>
<p>For example:<code>python usage -w3s</code></p>
<hr>
<h3 id="wildcard">Wildcard</h3>
<p>The <code>*</code> in the search bar works similarly to the wildcard in Linux.</p>
<hr>
<h3 id="search-for-similar-words">Search for Similar Words</h3>
<p>Use the <code>~</code> symbol. For example, to search for words similar to &ldquo;elderly,&rdquo; input <code>~elderly</code>. This will return pages that include words like &ldquo;senior,&rdquo; &ldquo;older,&rdquo; &ldquo;aged,&rdquo; and more, in addition to &ldquo;elderly.&rdquo;</p>
<hr>
<h3 id="search-multiple-keywords">Search Multiple Keywords</h3>
<p>Use <code>|</code> to separate search terms.</p>
<p>You can also use <code>OR</code> and <code>AND</code> keywords. Make sure to use parentheses <code>()</code> to organize the structure of your search.</p>
<hr>
<h3 id="search-within-a-specific-website-site">Search Within a Specific Website: <code>site:</code></h3>
<p>Use <code>site:url (keywords)</code> before the search query.</p>
<p>You can use parentheses <code>()</code> around similar filters to better organize the search structure.</p>
<hr>
<h3 id="search-related-websites-related">Search Related Websites: <code>related:</code></h3>
<p>Using <code>related:</code> helps you find websites related to a specific site.</p>
<p>For example, searching for <code>&quot;related:runoob.com&quot;</code> will return all websites related to <code>runoob.com</code>.</p>
<hr>
<h3 id="time-range-daterange-after-before">Time Range: <code>daterange: AFTER: BEFORE</code></h3>
<p>Use <code>&quot;daterange:&quot;</code> to search for content within a specific time range. For example, searching for <code>&quot;marathon daterange:2011-01-01..2022-01-01&quot;</code> will return results related to marathons between 2011 and 2022.</p>
<p>Use <code>&quot;AFTER:2020&quot;</code> to get content after the year 2020, and so on.</p>
<hr>
<h3 id="search-for-keywords-in-titles-intitle">Search for Keywords in Titles: <code>intitle:</code></h3>
<p>Use <code>&quot;intitle:&quot;</code> to search for pages that have a certain keyword in the title tag. For example, searching for <code>&quot;intitle: Google&quot;</code> will return results with <code>Google</code> in the title.</p>
<hr>
<h3 id="specify-image-size-imagesize">Specify Image Size: <code>imagesize:</code></h3>
<p>Use syntax like <code>imagesize:500x500</code> to find images of a suitable size.</p>
<hr>
<h3 id="file-type-filetype">File Type: <code>filetype:</code></h3>
<p>Use <code>&quot;filetype:&quot;</code> to search for specific types of files. For example, searching for <code>&quot;Python manual filetype:pdf&quot;</code> will return all PDFs related to the Python manual.</p>
<hr>
<h3 id="find-cached-versions-of-web-pages">Find Cached Versions of Web Pages</h3>
<p>The <code>&quot;cache:&quot;</code> operator allows you to find cached versions of web pages. Google generates cached versions so users can access pages even when the website is down.</p>
<hr>
<h3 id="who-linked-to-this-image-src">Who Linked to This Image? <code>src:</code></h3>
<p>The <code>src:</code> search operator will return web pages that reference the image URL provided in the <code>src</code> attribute.</p>
]]></content:encoded></item><item><title>Choose your licenses</title><link>https://www.parkerchenca.com/tech/choose-your-licenses/</link><pubDate>Thu, 10 Sep 2026 11:09:00 +0000</pubDate><guid>https://www.parkerchenca.com/tech/choose-your-licenses/</guid><description>Common licenses in one table</description><content:encoded><![CDATA[<blockquote>
<p>🔔 <strong>Prelude:</strong>
I sometimes wonder if adding a license to my campus homework is too serious.
Nevertheless, I still will add it.</p>
</blockquote>
<h2 id="-main">🖋️ Main</h2>
<table>
	<thead>
			<tr>
					<th>License</th>
					<th>Version</th>
					<th>Include License</th>
					<th>Include Source Code</th>
					<th>Trademark</th>
					<th>Status Change</th>
					<th>Commercial Use</th>
					<th>Distribution</th>
					<th>Modification</th>
					<th>Patent Right</th>
					<th>Private Use</th>
					<th>License Transfer</th>
					<th>No Liability</th>
					<th>No Trademark</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><strong>Apache License</strong></td>
					<td>2.0</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
			</tr>
			<tr>
					<td><strong>FreeBSD License</strong></td>
					<td></td>
					<td>Yes</td>
					<td></td>
					<td></td>
					<td></td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td></td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td></td>
			</tr>
			<tr>
					<td>2-Clause BSD License</td>
					<td></td>
					<td>Yes</td>
					<td></td>
					<td></td>
					<td></td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td></td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td></td>
			</tr>
			<tr>
					<td><strong>GNU General Public License(GPL)</strong></td>
					<td>2.0</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td></td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td></td>
					<td>Yes</td>
					<td>No</td>
					<td>Yes</td>
					<td></td>
			</tr>
			<tr>
					<td>GNU Lesser General Public License</td>
					<td>2.1</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td></td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td></td>
					<td>Yes</td>
					<td>No</td>
					<td>Yes</td>
					<td></td>
			</tr>
			<tr>
					<td><strong>GNU General Public License</strong></td>
					<td>3.0</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>No</td>
					<td>Yes</td>
					<td></td>
			</tr>
			<tr>
					<td>GNU Lesser General Public License</td>
					<td>3.0</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>No</td>
					<td>Yes</td>
					<td></td>
			</tr>
			<tr>
					<td><strong>MIT License</strong></td>
					<td></td>
					<td>Yes</td>
					<td></td>
					<td></td>
					<td></td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td></td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
			</tr>
			<tr>
					<td><strong>Mozilla Public License(MPL)</strong></td>
					<td>2.0</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td></td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>No</td>
					<td>Yes</td>
					<td>Yes</td>
			</tr>
			<tr>
					<td>Eclipse Public License</td>
					<td>1.0</td>
					<td>Yes</td>
					<td>Yes</td>
					<td></td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>No</td>
					<td>Yes</td>
					<td></td>
			</tr>
			<tr>
					<td>Affero General Public License</td>
					<td>3.0</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>No</td>
					<td>Yes</td>
					<td></td>
			</tr>
			<tr>
					<td>General Copyright</td>
					<td></td>
					<td>Yes</td>
					<td></td>
					<td></td>
					<td>Yes</td>
					<td>Yes</td>
					<td>Yes</td>
					<td>No</td>
					<td>No</td>
					<td>Yes</td>
					<td>No</td>
					<td></td>
					<td></td>
			</tr>
	</tbody>
</table>
<h3 id="in-short">In short?</h3>
<ol>
<li><strong>Completely Open Source</strong> -&gt; MIT License, BSD License</li>
<li><strong>Open Source, But Must Credit the Original Author</strong> -&gt; Apache License 2.0</li>
<li><strong>Open Source, Must Use the Same License (Copyleft)</strong> -&gt; GPL</li>
<li><strong>Allows Commercial Use</strong> -&gt; MIT License, BSD License, Apache License 2.0, GPL</li>
<li><strong>Allows Closed Source (Can Be Integrated into Proprietary Software)</strong> -&gt; MIT License, BSD License, Apache License 2.0</li>
<li><strong>Does Not Allow Closed Source (Must Remain Open Source)</strong> -&gt; GPL</li>
</ol>
]]></content:encoded></item></channel></rss>