Zig Variables Explained - Mutability, Scope, and Shadowing
Understanding variables, mutable and immutability, scope and shadowing of variables in Zig.
In this post, we are going to learn about variables in Zig.
Creating a Project
As we did in the last article, lets start by creating a project directory and initialize the zig project.
cd ~/projects
mkdir variables
cd variables
zig initAs we are writing a executable program, lets delete the `root.zig` file and remove all the code from `main.zig` to start from scratch.
Creating Variables
Just like some other languages, we can create mutable and immutable variables.
- Use const keyword to create an immutable variable
- Use var keyword to create a mutable variable
Let’s start by writing the main function in `main.zig` and create these two kinds of variables:
pub fn main() void {
const pi = 3.14;
var age = 25;
}Now, if you’ll run the code at this point, then you’ll get some errors about unused variables. The compiler will exactly locate where the problem is.
In Zig, every variable we define must be used. This is great because this will help us keep our code clean and eliminate unnecessary variables.
There is another great thing with Zig, if we are creating a mutable variable but we never mutated the value of that variable, then Zig will give an error saying we must use a const (immutable) variable instead of var (mutable) variable.
Now, lets change that to const:
In Zig, we can’t declare a variable and then in another statement initialize that variable. We need to declare and initialize the variable at the same time:
We can’t do this:
pub fn main() void {
var name;
name = “Ziggy”;
}If you must define a variable with no value, then use the `undefined` keyword as the value for that variable.
pub fn main() void {
var age: u8 = undefined;
age = 25;
}Here, as we are not initializing the variable with a certain value, we need to specify the data type of this variable.
We will learn about all the primitive data types in the next article
Variable Shadowing
In Zig, we can shadow a variable just like Rust. Let me show you an example and then I’ll explain what shadowing is:
pub fn main() void {
var scope = “outer scope”;
{
var scope = “inner scope”;
}
}In the example above, we declared a variable named scope twice, but in different scopes.
The inner scope variable shadows the outer one. This means that inside the inner block, the outer scope is temporarily hidden and the inner variable is used instead.
Once the inner block ends, the shadowed variable goes out of scope, and the outer scope becomes accessible again.
Shadowing is useful when you want to reuse variable names in smaller scopes without affecting the original variable, and Zig makes this behavior explicit and predictable.
Shadowing does not mutate the original variable, it simply creates a new one with the same name in a narrower scope.
In the next article, we will go through all the primitive data types of Zig. Till then Goodbye!

