Cover....1
Title Page....2
Copyright and Credits....3
Dedication....4
Contributors....5
Table of Contents....8
Preface....26
Part 1: Zig Fundamentals....34
Chapter 1: Safety First....36
Getting the most out of this book – get to know your free benefits....37
Next-gen reader....37
Interactive AI assistant (beta)....38
DRM-free PDF or ePub version ....38
Training your brain to think in Zig....39
Systems programming reimagined....40
The genesis of Zig – fixing what’s broken....41
The flaws of mainstream languages....42
The solution? Obviously, Zig....43
A modern alternative to C....44
Simplicity – focus on what matters....44
No hidden control flow....45
Compile-time execution....45
Tooling – ready to go, right out of the box....46
More than just a language....47
Why does Zig have its own build system?....47
A unified approach....47
Cross-compilation made easy....48
Maintain with Zig....48
Interoperability....49
Too good to be ignored....53
A new era begins....55
Safety....55
Where to use Zig....57
Summary....58
Chapter 2: Setting Up Your Playground....60
Installing Zig....61
Playing it safe or living on the edge: your first Zig dilemma....62
Stable or Bold....62
Linux: the land of choices....64
Windows: the land of path variables and PowerShell....65
Mac: the cult of brew....66
Verifying your installation....66
BTW, I use Arch Nix....66
The ZLS for smarter Zig coding....67
Building the ZLS from source....67
Integrating the ZLS....68
Using the ZLS in VS Code....68
Using the ZLS in Neovim....70
Installing the vim-plug plugin manager....71
Fine-tuning the ZLS....72
Finding the right spot for your zls.json file....73
Taking the ZLS to the next level....74
Defining a custom check step in your build.zig file....74
Activating your configuration....76
Zig setup: surprise test!....77
Summary....79
Chapter 3: Your First Zig Program....82
“Hello, World!”: Your first taste of Zig....82
Bringing in the Standard Library....83
Importing packages....84
zig run....85
Step 1: Building the executable manually....85
Step 2: Running the executable....86
Why go through this?....86
Variables....87
Shadowing....90
Identifiers....91
A quick word on primitive types....92
Basic debugging....92
Step 1: Building the program in debug mode....93
Step 2: Running the program....93
Step 3: What’s going on?....93
Understanding the byte pattern....93
std.debug....94
Maintaining consistency....95
Line endings: Keep it simple, keep it LF....95
Tabs versus spaces: Pick a side (spoiler: use spaces)....95
Byte order marks: Only at the start....95
The power of zig fmt....96
Building Zig projects....96
Step 1: Creating your project....96
Step 2: Your first build....97
Step 3: Running your program....97
Step 4: What’s inside the source code?....98
Step 5: Too many moving parts....98
Summary....99
Make it stick....99
Answers....105
Chapter 4: Control Flow, Loops, and Other Forms of Digital Domination....106
Technical requirements....107
Making choices with if, else, and switch (your code’s moral compass)....107
if as an expression....109
if with Boolean conditions: The classic that never gets old....110
if with union types....111
The elegant switch: Leveling up decision-making....112
Repeating actions....113
Iterating over a portion of a collection....115
Accessing indices....116
Iterating over multiple collections: Because one isn’t challenging enough....117
Using loops as expressions with else: Handling disappointment gracefully....118
Best practices, or how to sleep at night....121
Optional types: Because life (and code) isn’t always certain....123
What is the ?T type?....123
Embracing uncertainty in iteration....125
Labeled switches: When a regular switch just isn’t enough....127
Summary....133
Testing your knowledge....133
Chapter 5: Functions for the Efficient Programmer....138
Technical requirements....139
Blocks – keeping your variables on a tight leash....139
Shadowing – Zig doesn’t play that game....141
Functions....142
Parameters – accepting inputs....143
Return values – sending outputs back to the caller....144
The unreachable statement – asserting the impossible....147
Deferring decisions....150
Summary....152
Lock it in....153
Answers....155
Chapter 6: Error Handling....158
Technical requirements....158
Zig’s error handling philosophy....159
What’s an error value?....159
Enums: When you’re tired of magic numbers ruining your day....160
switch statements revisited: For when you need even more control flow....162
Enum literals: Saving you a few microseconds of typing....163
Non-exhaustive enums: Keep your options open....163
Introspection: When you want to play detective in your own code....165
Enum type information: Dive deeper if you dare....166
Unions....167
Tagged unions: Adding a tag for safety....168
Errors: Turning failures into manageable events....171
Error sets: Enumerating the possible mishaps....172
Handling errors with try and catch....172
Error unions: Combining errors with values....173
Handling error unions....174
Coercing error sets....174
The errdefer statement: Cleaning up after errors....176
Why Zig embraces error values....176
Why do error sets matter?....176
Error return traces: Breadcrumbs for when it all goes wrong....177
The anatomy of an error return trace....177
Error return traces are better than stack traces....178
Enabling and using error return traces....179
Why you’ll actually love error return traces....179
Summary....180
Reinforcing your understanding of enums, unions, and errors in Zig....181
Answers....187
Chapter 7: Testing Your Zig Code....190
Technical requirements....191
Unit testing: because debugging is a form of self-torture....191
Why bother with unit tests?....191
Understanding the test structure....192
Embracing failure (in your tests, not in life)....193
std.testing: Zig’s not-so-secret weapon for code confidence....194
Leveraging the testing allocator....197
Filtering tests....198
Making the most of std.testing....198
Test structure: Organizing your tests (so you can find them later)....199
The art of keeping tests close....199
Naming conventions: because vague names help no one....200
Leveraging doctests: Kill two birds with one stone....202
Running tests: the moment of truth (will It blend?)....203
Test Coverage....204
Using kcov: Step by step....205
Generating coverage for tests....206
Limitations and Considerations....209
Summary....209
Test time!....210
Answers....213
Part 2: Data, Memory, and Tools....216
Chapter 8: Organizing Data....218
Technical requirements....218
Arrays: fixed-size collections of things....219
A few good arrays....219
Because size matters....220
Iterating over arrays....220
Modifying arrays....221
Compile-time array magic....221
Initialize arrays to zero....222
Multidimensional arrays: like arrays, but more....222
Sentinel-terminated arrays: because sometimes you need a flag....223
Slices: dynamic views into arrays....224
Step 1: Arrays and their royal stubbornness....225
Step 2: Introducing slices (runtime flexibility)....226
Step 3: A more complex scenario – filtering and sub-slicing....229
Step 4: Treating strings as slices....231
Step 5: Sentinel-terminated slices (because some APIs are stuck in the past)....232
Structs: your own custom data (because you’re special)....233
Step 1: A simple struct (the basics)....234
Step 2: Adding functions to structs (methods, but not really)....235
Step 3: Namespaced declarations and empty structs....236
Step 4: Field parent pointers (fancy reflection)....237
Step 5: Default field values done right....238
Step 6: Packed structs (memory layout shenanigans)....239
Step 7: Anonymous structs and tuples....240
Summary....242
Let’s make this knowledge stick!....243
Chapter 9: Memory Management....248
Technical requirements....249
Stack and heap: The two-headed beast of memory....249
Memory and processes (at a glance)....249
Stack....249
Heap....250
Other sections (we swear they exist)....251
Pointers: The good, the bad, and the ugly (but mostly good)....251
Why bother with pointers?....251
Getting a pointer: & (address of)....252
Explicit mutability....253
Pointer semantics....253
Compile-time safety....254
Pointer array access....254
Converting between pointers and integers....255
volatile....257
volatile versus concurrency....258
Casting pointers: Loot boxes and mystery bytes....258
Why use @alignCast with @ptrCast?....259
Reinterpreting bits....259
Single-item versus many-item pointers....260
Slicing with pointers....261
Pointer arithmetic: A loaded gun....261
Allocation: The art of asking for more memory (and getting it)....262
Zig versus mainstream languages: The babysitters and the grown-ups....263
Allocators interface....263
Allocators in Zig....264
alloc: Grabbing memory manually....264
free: Return it or suffer....264
resize: Asking politely for more....265
create: Single-item allocation....265
destroy: Free that single item....265
Lifetime considerations....265
Testing allocators: std.testing.allocator....268
Testing your equipment....269
Handling allocation failures: std.testing.failing_allocator....270
FixedBufferAllocator: Your first real allocator....274
The GeneralPurposeAllocator(s): Plural? Yes, plural.....277
The page allocator: The unsung hero....279
The arena allocator: A playground for memory management....281
The elephant in the room: Safety, part 2....285
Zig’s design philosophy: Honest, explicit, and controlled....286
Zero-sized types: The phantom menace of memory management (but they have their uses)....287
A type that stores nothing....288
void versus anyopaque....289
Ignoring expressions....289
Shrinking your code with zero-sized types....289
Type conversion (casting): When your data needs a disguise....290
Type coercion: Safe and automatic....290
When coercion fails....291
C pointers special case....292
Peer type resolution....292
Summary....295
Chapter 10: The Standard Library....298
Technical requirements....298
Common data structures: ArrayLists, HashMaps, and other fun things ....299
Party Members: ArrayLists in Zig — the art of controlled chaos....299
init: raising the banner....299
append: the delusion of safety....300
Capacity: the chess game....300
The unmanaged horde....300
Insertions and removals: the dance of death....301
The sentinel gambit....301
The philosophy of pain....301
Epilogue: why bother?....302
HashMaps: the tavern brawlers of data structures....302
Key operations (pun intended)....302
The dark arts of hashing....303
Tombstones: the ghosts of hashes past....304
Adapt or perish: contexts and customization....304
Zig versus the world....304
Boss fight: test your gear....305
File I/O: reading, writing, and wrangling files like a boss ....305
Opening act: the filesystem dungeon....305
Opening files: negotiating with the file system’s bouncer....305
Reading files: from bytes to bragging rights....307
Writing files: carving your legacy into the disk....307
Binary files: telepathy for machines....308
Buffered I/O: the blazing-fast option....308
File sync: the ritual of flushing....309
File seeking: time travel for bytes....309
Error handling: Zig’s “No BS” policy....309
File permissions: the guardian spells....310
Hard links: the doppelgänger files....310
Final boss challenge: the atomic logger....311
The Zig filesystem creed....311
Untapped territories in Zig file operations: the lost scrolls ....311
File modes and flags: the fine print of file creation....311
Memory-mapped files: the necromancy of I/O....312
Disk space intel: the scout’s report....312
Symbolic link creation: traps for the unwary....313
Advanced error recovery: the phoenix protocol....313
Formatting and printing: making your output look pretty (or at least legible)....314
Why std.fmt? Precision meets flexibility....314
Core tools: crafting strings with purpose....314
Advanced techniques: precision, padding, and personality....315
Custom formatting: make your types shine....316
Quiz time: spot the mistake....317
Other utilities: random numbers, time, and more fun stuff....318
Randomness: choose your weapon wisely....318
Time: raw, unfiltered, and unapologetic....319
Why no DateTime?....319
Iterators: scalpels versus chainsaws....320
1. std.mem.SplitIterator....320
2. std.mem.TokenIterator....320
Sorting: no training wheels, no regrets....320
The Zig difference: no magic, no compromises....321
Final challenge....321
std.mem utilities: a comprehensive guide....322
Core operations....322
set....322
Memory manipulation....323
Advanced utilities....323
Iteration and splitting....324
Challenge solution: 64-byte chunk processor....324
Summary....325
Chapter 11: Packing....328
Technical requirements....329
The Zig build system: automating your workflow....329
zig init: your project’s starter kit (with free existential dread)....329
The yin and yang of Zig’s init twins....330
build.zig dissected: what’s in the box?....330
Using zig build....332
Building....332
Testing....332
Running....333
Customizing build.zig: from Meh to MVP**....334
Cross-compilation: Zig’s party trick (1 code base, 57 platform-specific bugs)....335
Tier 1: production-ready support....336
Tier 2: community-maintained support....336
Tier 3: experimental or minimal support....337
Tier 4: deprecated or legacy support....338
Using the target....338
Why do these matter?....342
Release modes....342
Optimizations: Debug versus Release (choose your poison)....342
Debug....344
ReleaseSafe....344
ReleaseFast....344
ReleaseSmall....345
Mix and match....346
Undefined behavior and granular control....347
Custom options....347
The build team....350
Steps: the atomic actions of a build pipeline....351
The taxonomy of steps....351
The DAG: Git’s angrier cousin....351
Declarative syntax: the illusion of simplicity....352
Custom steps: the build system’s escape hatch....352
The RPG side quest principle....353
The philosophy beneath....353
Modules....353
Code islands....354
Dependency hoarders....354
Configuration fetishists....354
The circle of (module) life: from declaration to domination....354
Declaration: the grand proclamation....355
Configuration: the fiddling and tweaking....355
Integration: joining the big leagues....355
Multi-module mania: when modules collide....356
The show must go on....358
The grand finale....358
Pop quiz: Are you smarter than a build script?....359
Generating docs: because code should be less cryptic than ancient runes....360
Doc comments: breadcrumbs for future-you....360
Generating docs: the compiler’s side hustle....361
Error set drama....361
Weaponize the build system....362
Package management: because reinventing the wheel is so last century....364
build.zig.zon: your new best friend (or worst enemy, the jury’s still out)....364
zig fetch: your command-line dependency fetcher....365
Putting dependencies to work: from build.zig.zon to @import....367
Important naming relationship....368
From fingerprint to fortress....368
Beyond the usual suspects....369
Cache: the memory of the compiler....370
Core concepts (how to avoid recompiling the universe)....371
Content-addressable storage (everything has a unique fingerprint)....371
Manifest files (the librarian’s secret notebook)....371
Cache workflow (the dance of hashes)....372
The Zig build cache directories....372
Real-world scenarios (proof that it works)....374
Performance and reliability (fast and correct)....376
Why this matters (the “so what?” section)....376
zig build --watch: your new best friend (who doesn’t talk back)....377
Why this is better than the old way....379
Summary....379
Part 3: Advanced Zig and Real-World Application....382
Chapter 12: Sophisticated Topics....384
Technical requirements....385
comptime: The time machine you didn’t know you needed....385
comptime basics....385
Type inference: Schrödinger’s integer....386
Every block, every time: The backbone of comptime....387
Zig’s double identity: Compile time versus runtime....389
Compile-time Zig: The master planner....389
Runtime Zig: The speed demon....389
The golden rule for calling comptime functions....390
The type supertype: Compile time’s bouncer....390
Compile-time exclusivity....391
Type functions: The type-generating powerhouses....391
Building simple types....391
Leveling up: Creating structs....392
Tools of the trade: @typeOf, @typeInfo, and @Type....394
@typeOf: The detective....394
@typeInfo: The magnifying glass....394
@Type: Bringing types to life....395
Reflection and metaprogramming....396
anytype: The Swiss Army knife of types....398
Common pitfalls: When types fight back....399
Mistake 1: Using anytype where type is required....399
Mistake 2: Confusing compile time with runtime contexts....400
Mistake 3: The “everything should be anytype” trap....401
Mistake 4: Forgetting about type coercion rules....402
Mistake 5: Type parameter naming confusion....403
comptime budgets: The branch quota....404
The override: What is @setEvalBranchQuota()?....404
Threads in Zig: Herding cats with a laser pointer....406
Spawning threads: Welcome to the Thunderdome....406
Sharing data: Mutexes are your bouncers....407
Mutexes: The bouncers of your nightclub....407
Atomics: The cheetahs of concurrency....408
Pitfalls: How to summon a segfault demon....410
Performance considerations: Don’t be a resource hog....411
Interoperability with C: When you need to borrow someone else’s tools (but make them work your way)....413
C: The cockroach of code (and why you’ll learn to love/hate it)....413
ABI....413
@cImport: Your gateway to the C underworld....414
Calling Zig from C: Exporting your chaos....416
Playing nice with C: Structs, alignment, and the quest for interoperability (RPG edition)....419
Extern structs: Your diplomatic passport to C....419
Alignment: The CPU’s picky preferences....419
Packed structs: The Tetris champions of memory....419
Bit-aligned pointers: Navigating the bitstream....420
The perils of [*c]T: Zig’s C pointer (and why you should (almost) never use it)....421
Summary....422
Chapter 13: Real-World Zig....424
Technical requirements....425
Command-line tools: automating your life (and annoy your coworkers)....425
FileGuard architecture: building your first real-world application....427
The file monitoring challenge....427
Design decisions: working smarter, not harder....428
Project structure: breaking it down....429
The implementation roadmap....430
Implementing file metadata: the foundation of change detection....431
The FileMetadata struct: identity, state, and ownership....431
Initializing file metadata: the birth of a tracking record....432
Memory management: the circle of life....433
Cloning metadata: sometimes you need a perfect copy....433
Content hashing: when size and timestamp aren’t enough....434
Cross-platform considerations: the beauty of abstraction....435
Putting it all together: the complete file metadata implementation....436
Building a file index: organizing your digital filing cabinet....436
The FileIndex struct: a tale of two maps....436
Initializing the index: setting up shop....438
Cleanup: leaving no trace behind....438
Adding files: populating your index....439
Lookup operations: finding your files....440
Cloning the index: sometimes you need a perfect copy....440
Removing files: when it’s time to say goodbye....442
Counting files: how big is your collection?....442
The power of dual indexing: path and inode lookups....443
Memory management: the path tracking mystery explained....443
Directory traversal: exploring your digital wilderness....444
The TraversalConfig: your expedition parameters....444
Pattern matching: your file-finding filter....445
The file filter: should we include this file?....446
The main traversal: your digital safari....446
Handling symbolic links: the portals of the filesystem....448
The traversal dance: how it all works together....449
Performance considerations: traversal isn’t free....450
Change detection: spot the differences in your digital world....451
Defining change types: building your detective’s notebook....451
Representing changes: the FileChange struct....452
The change journal: collecting your evidence....452
Detection configuration: customizing your detective work....453
The main detection algorithm: finding your culprits....454
Detecting file modifications: the devil in the details....456
The magic of move detection: inodes to the rescue....459
Building the command-line interface: making FileGuard user-friendly....460
Command-line options: giving users control....460
Parsing arguments: turning text into configuration....461
Displaying help: guiding lost souls....463
Running the monitor: the main event loop....463
Reporting changes: making results human-readable....467
Error handling: when things go wrong....469
Beyond the basics: professional CLI features....470
Tying it all together: the main program and beyond....471
Building and wrangling dependencies....472
Building and running FileGuard: from code to executable....474
Extending FileGuard: the road to professional use....475
Other project ideas: the sky’s the limit (or at least the memory limit)....475
Community resources: forums, chat rooms, and other dens of iniquity (we mean knowledge)....477
Contributing to Zig: open-source development for the greater good (and your resume)....478
The roadmap: Zig’s future plans (world domination, probably)....478
Zig’s impact: case studies and success stories (from humble beginnings to tech giants)....479
Summary....479
Chapter 14: Unlock Your Book’s Exclusive Benefits....482
How to unlock these benefits in three easy steps....482
Step 1....482
Step 2....483
Step 3....483
Need help?....484
Other Books You May Enjoy....488
Index....492
Master Zig's blend of safety and performance by building real-world systems applications, and learn memory management through to compile-time execution to create reliable software with full control and zero hidden behaviors
System programming has long forced developers to choose between safety and performance, but Zig changes the game with its no hidden control flow philosophy and explicit resource management. If you've struggled with memory leaks, undefined behavior, or cryptic compiler errors, Zig offers an alternative that puts you back in control.
Alex Rios, a seasoned software engineer with experience building high-throughput systems across fintech, telecom, and gaming industries, brings his unconventional system design approach and offers insight into Zig, as someone who's seen the limitations of existing languages firsthand.
You’ll get to grips with Zig's safety-centric design fundamentals, which will guide you through setting up your app development environment and writing your first programs. You'll then explore Zig's distinctive features in depth, such as explicit error handling, manual memory management, and compile-time execution. The book tackles each topic with a blend of technical depth and wit, ensuring you grasp not just the how but also the why behind Zig's design decisions.
By the end of this book, you'll be ready to build a complete application that interacts with the OS, third-party libraries, and C dependencies, as well as engage with Zig's growing community and contribute to its ecosystem.
This book is for developers looking to master efficient and safe programming with Zig. The target audience includes system programmers exploring manual memory management and safety features, embedded systems developers building high-performance software, WebAssembly enthusiasts creating web applications, programmers transitioning from Go or JavaScript for better control over memory and performance, and C/C++ developers seeking simplicity and low-level control without sacrificing safety or performance.