# Array Literals

### Array Literals

An array literal is the syntax you use to write array values directly in source code.

You already saw this form:

```zig
const numbers = [3]i32{ 10, 20, 30 };
```

This creates a fixed array with 3 elements. Each element has type `i32`.

The full shape is:

```zig
[3]i32{ 10, 20, 30 }
```

Read it as:

```text
an array of 3 i32 values, initialized with 10, 20, and 30
```

#### The Parts of an Array Literal

An array literal has two main parts:

```zig
[3]i32{ 10, 20, 30 }
```

The part before the braces is the array type:

```zig
[3]i32
```

The part inside the braces is the data:

```zig
{ 10, 20, 30 }
```

So this:

```zig
const numbers: [3]i32 = [3]i32{ 10, 20, 30 };
```

means:

```text
create a value of type [3]i32 and fill it with these 3 values
```

Usually, you do not need to write the type twice.

```zig
const numbers = [3]i32{ 10, 20, 30 };
```

This is enough because Zig can infer the variable type from the literal.

#### Letting Zig Count the Length

You can use `_` to ask Zig to count the number of elements:

```zig
const numbers = [_]i32{ 10, 20, 30 };
```

This has the same type as:

```zig
const numbers = [3]i32{ 10, 20, 30 };
```

The underscore does not mean “unknown forever.” It means “compiler, calculate this for me.”

After compilation, the type is still fixed:

```zig
[3]i32
```

This is common Zig style when the literal is written directly in the code.

```zig
const vowels = [_]u8{ 'a', 'e', 'i', 'o', 'u' };
```

The compiler sees 5 values, so the type is:

```zig
[5]u8
```

#### Empty Arrays

An array can have length zero.

```zig
const empty = [_]u8{};
```

This creates an array with no elements.

Its type is:

```zig
[0]u8
```

Zero-length arrays are not common in beginner code, but they are valid. They can appear in generic code, compile-time code, tests, and APIs where “no items” is a valid case.

#### All Elements Must Match the Element Type

In this array:

```zig
const numbers = [_]i32{ 10, 20, 30 };
```

each element must be usable as an `i32`.

This works:

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

This does not work:

```zig
const numbers = [_]i32{ 1, 2, "three" };
```

The string `"three"` is not an `i32`.

Zig does not silently guess a mixed array type. A fixed array has one element type, and every element must fit that type.

#### Array Literals with Explicit Variable Types

Sometimes the variable already has a type.

```zig
const numbers: [3]i32 = .{ 10, 20, 30 };
```

Here, the literal starts with a dot:

```zig
.{ 10, 20, 30 }
```

This means: use the type expected from the left side.

The left side says:

```zig
const numbers: [3]i32
```

So Zig knows the literal must be a `[3]i32`.

This form is very common in Zig.

```zig
const rgb: [3]u8 = .{ 255, 128, 0 };
```

The type is written once, on the variable. The initializer uses `.{ ... }`.

#### Why `.{ ... }` Exists

The dot literal is useful because Zig often knows the expected type from context.

For example:

```zig
fn printColor(color: [3]u8) void {
    _ = color;
}

pub fn main() void {
    printColor(.{ 255, 128, 0 });
}
```

The function expects `[3]u8`, so Zig can understand:

```zig
.{ 255, 128, 0 }
```

as:

```zig
[3]u8{ 255, 128, 0 }
```

This keeps code shorter without making it unclear.

#### Array Literals and Mutability

The literal itself is just a value. Mutability depends on the variable you assign it to.

This is immutable:

```zig
const numbers = [_]i32{ 10, 20, 30 };
```

You cannot change its elements.

```zig
numbers[0] = 99; // error
```

This is mutable:

```zig
var numbers = [_]i32{ 10, 20, 30 };
numbers[0] = 99;
```

The array now contains:

```text
99, 20, 30
```

The literal syntax does not decide mutability. `const` or `var` decides mutability.

#### Repeating Values

Zig can build an array by repeating a value.

```zig
const zeroes = [_]u8{0} ** 8;
```

This creates:

```text
0, 0, 0, 0, 0, 0, 0, 0
```

Its type is:

```zig
[8]u8
```

This is useful for buffers:

```zig
var buffer = [_]u8{0} ** 1024;
```

This creates 1024 bytes, all initialized to zero.

You can repeat other values too:

```zig
const ones = [_]i32{1} ** 5;
```

This creates:

```text
1, 1, 1, 1, 1
```

#### Concatenating Array Literals

Zig can concatenate arrays using `++`.

```zig
const a = [_]u8{ 1, 2 };
const b = [_]u8{ 3, 4 };

const c = a ++ b;
```

The result is:

```text
1, 2, 3, 4
```

The type of `c` is:

```zig
[4]u8
```

This also works directly with literals:

```zig
const digits = [_]u8{ '0', '1', '2' } ++ [_]u8{ '3', '4', '5' };
```

The result is a single array:

```zig
[6]u8
```

Array concatenation happens at compile time when the arrays are known at compile time.

#### Repetition and Concatenation Together

You can combine `**` and `++`.

```zig
const border = [_]u8{'='} ** 10 ++ [_]u8{'\n'};
```

This creates:

```text
========== newline
```

More precisely, it creates 11 bytes: ten `=` bytes and one newline byte.

This style is useful for constant data.

```zig
const header =
    [_]u8{'-'} ** 20 ++
    [_]u8{'\n'};
```

For large or dynamic strings, you will normally use other tools. But for fixed compile-time data, array literals are simple and efficient.

#### Nested Array Literals

Arrays can contain arrays.

```zig
const matrix = [2][3]i32{
    .{ 1, 2, 3 },
    .{ 4, 5, 6 },
};
```

This has type:

```zig
[2][3]i32
```

Read this as:

```text
an array of 2 rows, where each row is an array of 3 i32 values
```

Each row can use dot literal syntax because Zig already knows each row must be `[3]i32`.

This is equivalent to:

```zig
const matrix = [2][3]i32{
    [3]i32{ 1, 2, 3 },
    [3]i32{ 4, 5, 6 },
};
```

The shorter version is usually better:

```zig
const matrix = [2][3]i32{
    .{ 1, 2, 3 },
    .{ 4, 5, 6 },
};
```

#### Arrays of Struct Values

Array literals can contain structs.

```zig
const Point = struct {
    x: i32,
    y: i32,
};

const points = [_]Point{
    .{ .x = 0, .y = 0 },
    .{ .x = 10, .y = 20 },
    .{ .x = -5, .y = 3 },
};
```

The type of `points` is:

```zig
[3]Point
```

Each element is a `Point`.

This is a common pattern for lookup tables, test cases, coordinates, tokens, and configuration data.

#### Arrays of Anonymous Structs

Zig can also infer an anonymous struct type in some contexts.

```zig
const items = .{
    .{ .name = "apple", .price = 100 },
    .{ .name = "banana", .price = 80 },
};
```

This does not create a normal fixed array in the same simple way as `[N]T`. It creates a tuple-like value where the fields are known at compile time.

For beginners, prefer explicit array types when you want an array:

```zig
const Item = struct {
    name: []const u8,
    price: u32,
};

const items = [_]Item{
    .{ .name = "apple", .price = 100 },
    .{ .name = "banana", .price = 80 },
};
```

This is clearer and easier to pass to functions.

#### Array Literals and Strings

String literals are closely related to arrays of bytes.

```zig
const name = "zig";
```

This stores the bytes for:

```text
z i g
```

You can also write those bytes manually:

```zig
const name_bytes = [_]u8{ 'z', 'i', 'g' };
```

But these are not exactly the same type. String literals in Zig have sentinel information, which we will cover later.

For now, the important point is simple: text in Zig is stored as bytes, and array literals are one way to write bytes directly.

#### Common Mistake: Wrong Length

This is an error:

```zig
const numbers = [2]i32{ 10, 20, 30 };
```

The type says 2 elements, but the literal gives 3.

This is also an error:

```zig
const numbers = [4]i32{ 10, 20, 30 };
```

The type says 4 elements, but the literal gives 3.

The length and the number of values must match.

Use `_` when you want the compiler to count:

```zig
const numbers = [_]i32{ 10, 20, 30 };
```

#### Common Mistake: Confusing Arrays and Slices

This is an array:

```zig
const numbers = [_]i32{ 10, 20, 30 };
```

Its type is:

```zig
[3]i32
```

This is a slice:

```zig
const slice = numbers[0..];
```

Its type is:

```zig
[]const i32
```

An array owns the elements. A slice points to elements stored somewhere else.

Array literals create arrays, not slices. You can create a slice from an array after the array exists.

#### Common Mistake: Forgetting the Dot Literal Needs Context

This works:

```zig
const numbers: [3]i32 = .{ 10, 20, 30 };
```

The type is known from the left side.

This may not work in places where Zig has no expected type:

```zig
const numbers = .{ 10, 20, 30 };
```

This creates a tuple-like value, not a plain `[3]i32`.

For a real array, write:

```zig
const numbers = [_]i32{ 10, 20, 30 };
```

or:

```zig
const numbers: [3]i32 = .{ 10, 20, 30 };
```

#### A Complete Example

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

pub fn main() void {
    const primes = [_]u32{ 2, 3, 5, 7, 11 };
    const zeroes = [_]u8{0} ** 4;
    const more_primes = primes ++ [_]u32{ 13, 17 };

    std.debug.print("primes:\n", .{});
    for (primes, 0..) |value, index| {
        std.debug.print("  primes[{}] = {}\n", .{ index, value });
    }

    std.debug.print("zeroes length = {}\n", .{zeroes.len});

    std.debug.print("more_primes:\n", .{});
    for (more_primes, 0..) |value, index| {
        std.debug.print("  more_primes[{}] = {}\n", .{ index, value });
    }
}
```

This program shows three array literal patterns:

```zig
const primes = [_]u32{ 2, 3, 5, 7, 11 };
```

A normal array literal with inferred length.

```zig
const zeroes = [_]u8{0} ** 4;
```

A repeated array literal.

```zig
const more_primes = primes ++ [_]u32{ 13, 17 };
```

A concatenated array.

#### Summary

An array literal writes array data directly in your code.

The most common forms are:

```zig
const a = [3]i32{ 1, 2, 3 };
const b = [_]i32{ 1, 2, 3 };
const c: [3]i32 = .{ 1, 2, 3 };
```

Use `[N]T{ ... }` when you want to state the length directly.

Use `[_]T{ ... }` when you want Zig to count the elements.

Use `.{ ... }` when the expected type is already known.

Array literals are small, direct, and precise. They are one of the first places where Zig’s type system becomes visible: the number of elements and the type of each element are checked before the program runs.

