Something went wrong. Try again.
ssg
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839<!DOCTYPE HTML><html lang="en" data-theme="light"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Zig</title><link rel="stylesheet" href="../styles/reset.css"><link rel="stylesheet" href="../styles/prima.css"></head><body class="r-page"><main class="main-content"><h1>Zig</h1><div class="metadata"><span class="date">2026-09-01</span><span class="nodes"><a href="../n/zig.html">zig</a></span></div><div class="description">Learning notes for zig programming language</div><pre><code><span class='keyword'>const</span> <span class='variable'>std</span> <span class='operator'>=</span> <span class='function builtin'>@import</span><span class='punctuation bracket'>(</span><span class='string'>"std"</span><span class='punctuation bracket'>)</span><span class='punctuation delimiter'>;</span><span class='keyword'>const</span> <span class='variable'>Io</span> <span class='operator'>=</span> <span class='variable'>std</span><span class='punctuation delimiter'>.</span><span class='property'>Io</span><span class='punctuation delimiter'>;</span></code></pre><h1 id="different-ways-to-print">Different ways to print</h1><blockquote class="callout">The methods mentioned here are by no means exhaustive. </blockquote><h2 id="debug-print">Debug print</h2><p>Writes to stderr and ignores errors (hence no <code class="inlinecode">try</code>), bypasses the <code class="inlinecode">Io</code> interface. Ideally we should delete every occurence of <code class="inlinecode">std.debug.print</code> after debugging.</p><pre><code><span class='function'>fn</span> <span class='function'>@"<span class='string'>std-debug-print</span>"</span><span class='punctuation bracket'>(</span><span class='punctuation bracket'>)</span> <span class='type builtin'>void</span><span class='punctuation bracket'>{</span> <span class='variable'>std</span><span class='punctuation delimiter'>.</span><span class='property'>debug</span><span class='punctuation delimiter'>.</span><span class='variable'>print</span><span class='punctuation bracket'>(</span><span class='string'>"Hello, {s}!<span class='constant builtin'>\n</span>"</span><span class='punctuation delimiter'>,</span> <span class='punctuation bracket'>.{</span><span class='string'>"std.debug.print"</span><span class='punctuation bracket'>}</span><span class='punctuation bracket'>)</span><span class='punctuation delimiter'>;</span><span class='punctuation bracket'>}</span></code></pre><h2 id="iowriterhttpsziglangorgdocumentationmasterstdstdiowriter"><a href="https://ziglang.org/documentation/master/std/#std.Io.Writer">Io.Writer</a></h2><blockquote class="callout">You'd probably want to watch <a href="https://youtu.be/f30PceqQWko?si=KIHJCgBYx7sStJk8">this talk</a> by Andrew Kelly and <a href="https://joegm.github.io/blog/inside-zigs-new-writer-interface/#one-writer-to-rule-them-all">this post</a> by Joe Mckay.</blockquote><p><code class="inlinecode">Io.File.stderr().writerStreaming(io, &buffer)</code> returns <code class="inlinecode">Io.File.Writer</code> and we can use its <code class="inlinecode">interface</code> i.e. <code class="inlinecode">Io.Writer</code> to actually write to <code class="inlinecode">stderr</code>, the buffer we hand is managed through the interface (<strong>buffering in the interface</strong>). And don't forget to <code class="inlinecode">flush</code>.</p><blockquote class="callout">There are two modes streaming and no-streaming for <code class="inlinecode">Io.File.Writer</code>. We should take the streaming variant for stdout/stderr(/stdin).</blockquote><pre><code><span class='function'>fn</span> <span class='function'>@"<span class='string'>std-Io-Writer</span>"</span><span class='punctuation bracket'>(</span><span class='variable'>io</span><span class='operator'>:</span> <span class='variable'>Io</span><span class='punctuation bracket'>)</span> <span class='operator'>!</span><span class='type builtin'>void</span><span class='punctuation bracket'>{</span> <span class='keyword'>var</span> <span class='variable'>stderr_buf</span><span class='operator'>:</span> <span class='punctuation bracket'>[</span><span class='number'>1024</span><span class='punctuation bracket'>]</span><span class='type builtin'>u8</span> <span class='operator'>=</span> <span class='constant builtin'>undefined</span><span class='punctuation delimiter'>;</span> <span class='keyword'>var</span> <span class='variable'>stderr_writer</span> <span class='operator'>=</span> <span class='variable'>Io</span><span class='punctuation delimiter'>.</span><span class='property'>File</span><span class='punctuation delimiter'>.</span><span class='variable'>stderr</span><span class='punctuation bracket'>(</span><span class='punctuation bracket'>)</span><span class='punctuation delimiter'>.</span><span class='variable'>writerStreaming</span><span class='punctuation bracket'>(</span><span class='variable'>io</span><span class='punctuation delimiter'>,</span> <span class='operator'>&</span><span class='variable'>stderr_buf</span><span class='punctuation bracket'>)</span><span class='punctuation delimiter'>;</span> <span class='keyword'>const</span> <span class='variable'>stderr</span> <span class='operator'>=</span> <span class='operator'>&</span><span class='variable'>stderr_writer</span><span class='punctuation delimiter'>.</span><span class='property'>interface</span><span class='punctuation delimiter'>;</span> <span class='keyword'>defer</span> <span class='variable'>stderr</span><span class='punctuation delimiter'>.</span><span class='variable'>flush</span><span class='punctuation bracket'>(</span><span class='punctuation bracket'>)</span> <span class='keyword'>catch</span> <span class='punctuation bracket'>{</span><span class='punctuation bracket'>}</span><span class='punctuation delimiter'>;</span>
<span class='keyword'>try</span> <span class='variable'>stderr</span><span class='punctuation delimiter'>.</span><span class='variable'>print</span><span class='punctuation bracket'>(</span><span class='string'>"Hello, {s}!<span class='constant builtin'>\n</span>"</span><span class='punctuation delimiter'>,</span> <span class='punctuation bracket'>.{</span><span class='string'>"std.Io.Writer"</span><span class='punctuation bracket'>}</span><span class='punctuation bracket'>)</span><span class='punctuation delimiter'>;</span><span class='punctuation bracket'>}</span></code></pre><h3 id="thread-safe-stderrhttpsziglangorgdocumentationmasterstdstddebuglockstderr"><a href="https://ziglang.org/documentation/master/std/#std.debug.lockStderr">Thread-safe stderr</a></h3><p><code class="inlinecode">std.debug.lockStderr</code> allows the caller to freely write to stderr until unlockStderr is called. During the lock, any <code class="inlinecode">std.Progress</code> information is cleared from the standard stream. As <code class="inlinecode">std.debug.print</code>, this ignores <code class="inlinecode">Io</code> and should be deleted after debugging.</p><pre><code><span class='function'>fn</span> <span class='function'>@"<span class='string'>std-debug-lockStderr</span>"</span><span class='punctuation bracket'>(</span><span class='punctuation bracket'>)</span> <span class='operator'>!</span><span class='type builtin'>void</span><span class='punctuation bracket'>{</span> <span class='keyword'>const</span> <span class='variable'>stderr</span> <span class='operator'>=</span> <span class='variable'>std</span><span class='punctuation delimiter'>.</span><span class='property'>debug</span><span class='punctuation delimiter'>.</span><span class='variable'>lockStderr</span><span class='punctuation bracket'>(</span><span class='operator'>&</span><span class='punctuation bracket'>.{</span><span class='punctuation bracket'>}</span><span class='punctuation bracket'>)</span><span class='punctuation delimiter'>.</span><span class='variable'>terminal</span><span class='punctuation bracket'>(</span><span class='punctuation bracket'>)</span><span class='punctuation delimiter'>.</span><span class='property'>writer</span><span class='punctuation delimiter'>;</span> <span class='keyword'>defer</span> <span class='variable'>std</span><span class='punctuation delimiter'>.</span><span class='property'>debug</span><span class='punctuation delimiter'>.</span><span class='variable'>unlockStderr</span><span class='punctuation bracket'>(</span><span class='punctuation bracket'>)</span><span class='punctuation delimiter'>;</span> <span class='comment'>// flushing is performed automatically</span>
<span class='keyword'>try</span> <span class='variable'>stderr</span><span class='punctuation delimiter'>.</span><span class='variable'>print</span><span class='punctuation bracket'>(</span><span class='string'>"Hello, {s}!<span class='constant builtin'>\n</span>"</span> <span class='punctuation delimiter'>,</span> <span class='punctuation bracket'>.{</span><span class='string'>"std.debug.lockStderr"</span><span class='punctuation bracket'>}</span><span class='punctuation bracket'>)</span><span class='punctuation delimiter'>;</span><span class='punctuation bracket'>}</span></code></pre><p>Alternatively we can use <code class="inlinecode">std.Io.lockStderr</code> to perform application-level writes to stderr.</p><pre><code><span class='function'>fn</span> <span class='function'>@"<span class='string'>std-Io-lockStderr</span>"</span><span class='punctuation bracket'>(</span><span class='variable'>io</span><span class='operator'>:</span> <span class='variable'>Io</span><span class='punctuation bracket'>)</span> <span class='operator'>!</span><span class='type builtin'>void</span><span class='punctuation bracket'>{</span> <span class='keyword'>var</span> <span class='variable'>stderr_buf</span><span class='operator'>:</span> <span class='punctuation bracket'>[</span><span class='number'>1024</span><span class='punctuation bracket'>]</span><span class='type builtin'>u8</span> <span class='operator'>=</span> <span class='constant builtin'>undefined</span><span class='punctuation delimiter'>;</span> <span class='keyword'>var</span> <span class='variable'>locked</span> <span class='operator'>=</span> <span class='keyword'>try</span> <span class='variable'>io</span><span class='punctuation delimiter'>.</span><span class='variable'>lockStderr</span><span class='punctuation bracket'>(</span><span class='operator'>&</span><span class='variable'>stderr_buf</span><span class='punctuation delimiter'>,</span> <span class='constant builtin'><span class='keyword'>null</span></span><span class='punctuation bracket'>)</span><span class='punctuation delimiter'>;</span> <span class='keyword'>defer</span> <span class='variable'>io</span><span class='punctuation delimiter'>.</span><span class='variable'>unlockStderr</span><span class='punctuation bracket'>(</span><span class='punctuation bracket'>)</span><span class='punctuation delimiter'>;</span>
<span class='keyword'>const</span> <span class='variable'>stderr</span> <span class='operator'>=</span> <span class='variable'>locked</span><span class='punctuation delimiter'>.</span><span class='variable'>terminal</span><span class='punctuation bracket'>(</span><span class='punctuation bracket'>)</span><span class='punctuation delimiter'>.</span><span class='property'>writer</span><span class='punctuation delimiter'>;</span>
<span class='keyword'>try</span> <span class='variable'>stderr</span><span class='punctuation delimiter'>.</span><span class='variable'>print</span><span class='punctuation bracket'>(</span><span class='string'>"Hello, {s}!<span class='constant builtin'>\n</span>"</span> <span class='punctuation delimiter'>,</span> <span class='punctuation bracket'>.{</span><span class='string'>"std.Io.lockStderr"</span><span class='punctuation bracket'>}</span><span class='punctuation bracket'>)</span><span class='punctuation delimiter'>;</span><span class='punctuation bracket'>}</span></code></pre><p>To conclude, use <code class="inlinecode">debug</code> for informal/debug-only diagnostics. Take a lock when e.g. a multi-write writer mustn't interleave with other writers.</p><pre class="verbatim"><code>ϗ zig build-exe zig-notes.zig && ./zig-notesHello, std.debug.print!Hello, std.Io.Writer!Hello, std.debug.lockStderr!Hello, std.Io.lockStderr!</code></pre><pre><code><span class='keyword'>pub</span> <span class='function'>fn</span> <span class='function'>main</span><span class='punctuation bracket'>(</span><span class='variable'>init</span><span class='operator'>:</span> <span class='variable'>std</span><span class='punctuation delimiter'>.</span><span class='property'>process</span><span class='punctuation delimiter'>.</span><span class='property'>Init</span><span class='punctuation bracket'>)</span> <span class='operator'>!</span><span class='type builtin'>void</span><span class='punctuation bracket'>{</span> <span class='variable'>@"<span class='string'>std-debug-print</span>"</span><span class='punctuation bracket'>(</span><span class='punctuation bracket'>)</span><span class='punctuation delimiter'>;</span> <span class='keyword'>try</span> <span class='variable'>@"<span class='string'>std-Io-Writer</span>"</span><span class='punctuation bracket'>(</span><span class='variable'>init</span><span class='punctuation delimiter'>.</span><span class='property'>io</span><span class='punctuation bracket'>)</span><span class='punctuation delimiter'>;</span> <span class='keyword'>try</span> <span class='variable'>@"<span class='string'>std-debug-lockStderr</span>"</span><span class='punctuation bracket'>(</span><span class='punctuation bracket'>)</span><span class='punctuation delimiter'>;</span> <span class='keyword'>try</span> <span class='variable'>@"<span class='string'>std-Io-lockStderr</span>"</span><span class='punctuation bracket'>(</span><span class='variable'>init</span><span class='punctuation delimiter'>.</span><span class='property'>io</span><span class='punctuation bracket'>)</span><span class='punctuation delimiter'>;</span><span class='punctuation bracket'>}</span></code></pre><p>TODO</p><p class="l1-list"><code class="inlinecode">Io.Reader</code> & <code class="inlinecode">Io.Writer</code></p><p class="l1-list">reflexion</p></main><nav class="bottom-nav"><a href="../index.html">⌂</a><a href="../feed.xml">⌗</a><a href="../license">©</a><a href="#" id="theme-toggle" title="toggle theme">◐</a></nav><script>MathJax = { loader: { load: ['ui/lazy'] }, options: { skipHtmlTags: ['script','noscript','style','textarea','pre'], lazyMargin: '300px', renderActions: { find: [10, function(doc) { for (const node of document.querySelectorAll('.math-block')) { const math = new doc.options.MathItem( node.textContent, doc.inputJax[0], true ); const text = document.createTextNode(''); node.parentNode.replaceChild(text, node); math.start = {node: text, delim: '', n: 0}; math.end = {node: text, delim: '', n: 0}; doc.math.push(math); } for (const node of document.querySelectorAll('.inlinemath')) { const math = new doc.options.MathItem( node.textContent, doc.inputJax[0], false ); const text = document.createTextNode(''); node.parentNode.replaceChild(text, node); math.start = {node: text, delim: '', n: 0}; math.end = {node: text, delim: '', n: 0}; doc.math.push(math); } }, ''] } }, tex: { inlineMath: [], displayMath: [], packages: {'[+]': ['ams', 'boldsymbol']} }, svg: { fontCache: 'global' }};</script><script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js" defer=""></script><script>document.addEventListener('DOMContentLoaded', function() { var themeToggle = document.getElementById('theme-toggle'); var html = document.documentElement; var savedTheme = localStorage.getItem('theme') || 'light'; html.setAttribute('data-theme', savedTheme); if (!themeToggle) return; themeToggle.addEventListener('click', function(e) { e.preventDefault(); var currentTheme = html.getAttribute('data-theme'); var newTheme = currentTheme === 'light' ? 'dark' : 'light'; html.setAttribute('data-theme', newTheme); localStorage.setItem('theme', newTheme); });});</script><script>document.addEventListener('DOMContentLoaded', function() { var nav = document.querySelector('.bottom-nav'); if (!nav) return; var thr = 32; function upd() { var y = window.scrollY || document.documentElement.scrollTop; var max = document.documentElement.scrollHeight - window.innerHeight; var sht = max < thr ? y > 0 : y >= thr; nav.classList.toggle('is-visible', sht); } window.addEventListener('scroll', upd, { passive: true }); upd();});</script></body></html>