# Struct Declarations

### Struct Declarations

A struct is a type made from named fields.

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

This declares a type named `Point`. It has two fields, `x` and `y`. Both fields have type `i32`.

A value of this type is written with a struct literal:

```zig
const p = Point{
    .x = 10,
    .y = 20,
};
```

The field names are part of the literal. This makes the code clear when a struct has many fields.

A complete program:

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

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

pub fn main() void {
    const p = Point{
        .x = 10,
        .y = 20,
    };

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

The output is:

```text
x = 10, y = 20
```

Fields are selected with the dot operator:

```zig
p.x
p.y
```

The dot is used both when constructing a value and when reading a field. In a literal, `.x = 10` means "set the field named `x`." In an expression, `p.x` means "read the field `x` from `p`."

A struct value may be mutable.

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

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

pub fn main() void {
    var p = Point{
        .x = 10,
        .y = 20,
    };

    p.x = 30;

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

The output is:

```text
x = 30, y = 20
```

The variable `p` is declared with `var`, so its fields may be changed. If `p` were declared with `const`, the assignment to `p.x` would be rejected.

A struct can contain fields of different types.

```zig
const User = struct {
    id: u64,
    name: []const u8,
    active: bool,
};
```

Here `name` is a slice of constant bytes. In small programs, this is the usual type for a string value.

```zig
const user = User{
    .id = 1,
    .name = "alice",
    .active = true,
};
```

The type of `"alice"` fits `[]const u8`.

Struct declarations may be nested inside other declarations.

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

pub fn main() void {
    const Pair = struct {
        left: i32,
        right: i32,
    };

    const pair = Pair{
        .left = 3,
        .right = 4,
    };

    std.debug.print("{d}, {d}\n", .{ pair.left, pair.right });
}
```

A struct type can also be anonymous. This is useful for small temporary values.

```zig
const value = .{
    .name = "zig",
    .year = 2026,
};
```

Here Zig infers an anonymous struct type. The value has fields named `name` and `year`.

Anonymous structs are often used as arguments to formatting functions:

```zig
std.debug.print("{s} {d}\n", .{ "Zig", 2026 });
```

The expression `.{ "Zig", 2026 }` is also an anonymous struct, but with numbered fields instead of named fields. This form is called a tuple.

A struct may have default field values.

```zig
const Config = struct {
    verbose: bool = false,
    retries: u8 = 3,
};
```

Then a literal may omit those fields:

```zig
const config = Config{};
```

This is the same as:

```zig
const config = Config{
    .verbose = false,
    .retries = 3,
};
```

A literal may override only the fields it needs:

```zig
const config = Config{
    .verbose = true,
};
```

Now `verbose` is true and `retries` is still 3.

Structs may contain declarations as well as fields.

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

    const zero = Point{
        .x = 0,
        .y = 0,
    };
};
```

The declaration `zero` belongs to the namespace of `Point`.

It is accessed with:

```zig
Point.zero
```

A struct is both a layout of data and a namespace. This is important in Zig. Functions associated with a type are just declarations inside the struct. There is no separate class system.

For now, use a struct when several values should move together under one name.

```zig
const Rectangle = struct {
    width: u32,
    height: u32,
};
```

This is clearer than passing two unrelated integers through the program.

Exercises.

7-1. Define a struct named `Book` with fields `title`, `pages`, and `published`.

7-2. Create a `Book` value and print its fields.

7-3. Define a struct named `Counter` with one field, `value: u32`. Make a mutable counter and increment it.

7-4. Define a `Config` struct with default values. Create one value using all defaults, and another value overriding one field.

