# Variables and Constants

### Variables and Constants

A program stores values so it can use them later. In Zig, you store values with two main keywords:

```zig
const
var
```

Use `const` when the value will not change.

Use `var` when the value can change.

This is one of the first important habits in Zig: prefer `const` first. Only use `var` when you truly need to modify the value.

#### Constants

A constant is a named value that cannot be changed after it is created.

```zig
const age = 30;
```

This creates a name called `age` and gives it the value `30`.

You can use it later:

```zig
const std = @import("std");

pub fn main() void {
    const age = 30;

    std.debug.print("Age: {}\n", .{age});
}
```

Output:

```text
Age: 30
```

The value of `age` cannot be changed:

```zig
const age = 30;
age = 31; // error
```

Zig rejects this because `age` was declared with `const`.

This is useful. It prevents accidental changes.

#### Variables

A variable is a named value that can be changed.

```zig
var count = 0;
```

Now `count` can be updated:

```zig
const std = @import("std");

pub fn main() void {
    var count = 0;

    count = count + 1;
    count = count + 1;

    std.debug.print("Count: {}\n", .{count});
}
```

Output:

```text
Count: 2
```

Use `var` when the value represents something that changes over time: a counter, an index, a temporary buffer, a running total, or a mutable state.

#### Zig Wants You to Be Honest

Zig checks whether a variable really needs to be mutable.

This code is suspicious:

```zig
var x = 10;
std.debug.print("{}\n", .{x});
```

The value `x` never changes. Zig may tell you to use `const` instead.

The better version is:

```zig
const x = 10;
std.debug.print("{}\n", .{x});
```

This makes the code clearer. A reader can immediately know that `x` will not change.

#### Type Inference

Zig can often figure out the type from the value.

```zig
const x = 10;
const name = "Zig";
const enabled = true;
```

Here, Zig infers the types:

```zig
const x: comptime_int = 10;
const name: *const [3:0]u8 = "Zig";
const enabled: bool = true;
```

You do not need to write those types manually at the start. For beginners, it is usually better to let Zig infer simple local values.

But you can also write the type yourself:

```zig
const age: u8 = 30;
var count: i32 = 0;
const pi: f64 = 3.14159;
```

The syntax is:

```zig
const name: Type = value;
var name: Type = value;
```

Read this as:

```text
create name with type Type and value value
```

#### Basic Example

```zig
const std = @import("std");

pub fn main() void {
    const language = "Zig";
    const year: u16 = 2026;

    var score: i32 = 0;
    score = score + 10;
    score = score + 5;

    std.debug.print("{s} in {}\n", .{ language, year });
    std.debug.print("Score: {}\n", .{score});
}
```

Output:

```text
Zig in 2026
Score: 15
```

In this example:

```zig
const language = "Zig";
const year: u16 = 2026;
```

These do not change, so they are constants.

```zig
var score: i32 = 0;
score = score + 10;
score = score + 5;
```

This changes, so it is a variable.

#### Assignment

Assignment means giving a new value to an existing variable.

```zig
var n = 5;
n = 8;
```

After this code runs, `n` contains `8`.

You can assign only to something declared with `var`.

```zig
const n = 5;
n = 8; // error
```

A constant has one value. Once created, it cannot be reassigned.

#### Declaration vs Assignment

These two ideas are different.

Declaration creates the name:

```zig
var count: i32 = 0;
```

Assignment changes the value later:

```zig
count = 1;
```

You can combine declaration and initial value in one line:

```zig
const x = 10;
```

This is the common form.

#### Mutable Does Not Mean Careless

`var` should not be used just because it feels convenient.

This is weak code:

```zig
var max_connections = 100;
```

If `max_connections` never changes, it should be:

```zig
const max_connections = 100;
```

That small choice matters. In a large program, every mutable value is something the reader must track. Constants reduce the amount of state in the program.

Good Zig code uses `const` heavily.

#### Shadowing

Zig does not allow you to declare a local variable with the same name in the same scope.

```zig
const x = 10;
const x = 20; // error
```

This prevents confusion. If a name already means one thing, Zig does not let you reuse it in the same block.

You can create a new scope with braces:

```zig
const std = @import("std");

pub fn main() void {
    const x = 10;

    {
        const y = 20;
        std.debug.print("{} {}\n", .{ x, y });
    }
}
```

The name `y` exists only inside the inner block.

#### Uninitialized Variables

Sometimes you may want to declare a variable before giving it a real value.

Zig allows this with `undefined`:

```zig
var x: i32 = undefined;
x = 42;
```

This means: create `x`, but its starting value is not meaningful.

Be careful. Reading an undefined value is a bug.

```zig
var x: i32 = undefined;
std.debug.print("{}\n", .{x}); // bug
```

Use `undefined` only when you are sure the value will be assigned before it is read.

For beginners, prefer immediate initialization:

```zig
const x: i32 = 42;
```

#### Constants Can Hold Complex Values

A constant does not mean the value must be small.

You can use `const` for arrays, structs, imports, functions, and many other things.

```zig
const numbers = [_]i32{ 1, 2, 3, 4 };
```

This creates a constant array.

```zig
const std = @import("std");
```

This creates a constant binding to the standard library import.

In Zig, `const` is not only for numbers. It means the name cannot be reassigned.

#### The Main Rule

Start with `const`.

Change it to `var` only when the value must change.

```zig
const name = "Ada"; // good: does not change

var counter: usize = 0; // good: changes over time
counter += 1;
```

This habit makes Zig code simpler, safer, and easier to read.

