Structs

for Zig 0.15.2 Buy

Structs

With structs, we define data structures composed of named fields with concrete types. We use this syntax to define a struct:


const StructName = struct {

     field_name: type,

      …

     field_nameN: type,

}; 


Structs are especially useful for creating complex data types, objects with methods, and combinations of both. We'll see more of this when we talk about Generics in Chapter 8.

Looking around, the player realizes: this is almost a junkyard in the middle of the sea. The broken drones, disassembled parts, loose cables between scattered modules, arranged by him in his “ordered chaos”, don’t help. Beside him, 1KR, his “son” and loyal companion in one of his many reincarnations. He still remembers when the boy was a dog a few years ago. Escaping the island won’t be easy.

A couple of hours ago, the plan worked almost perfectly, and using the electromagnetic pulse, the pair of ARP1s guarding the beach access dropped like two giant flies, crashing mid-air. Of course, both the pulse and the impact left some damage.

- Smashed a bit more than we wanted, huh, pa?

- Yeah, you did a great job, son. In any case, we need to check how useful they still are to get us out of here.

The shifting maze of the caves was now behind them, hiding its horrors and the furious creature still raging over its failure to kill them. Trying to imprison the very creator of the Labyrinth inside it is, at the very least, stupid, and says a lot about the intelligence of the Governor. The cave creature, contrary to popular belief, may have inherited its extreme stupidity from the incompetent ruler, its human “father”… haha, and the horns too, now that I think about it. Funny, the player thinks as he starts the test. It should’ve been a joke… for a very select audience.

Remember tuples? A tuple is simply an anonymous struct whose fields have no names. Even though its elements are grouped like in a struct, we access them by index.

Structs can contain any type of data, including other structs and enums.

Here we use the EngineStatus enum, previously defined, to describe the current state of a motor.

struct_engine.zig

const std = @import("std");

const print = std.debug.print;

const EngineStatus = enum(i8) {

    failure = -1, off = 0, on = 1, testing = 2, autorepairing = 3,

};

const DroneEngine = struct {

    var n_total_failed: u8 = 0;

    const N_MAX_RPM: u32 = 8500;

    const N_MIN_HEALTH: u32 = 75;

    e_status: EngineStatus,

    n_health: u8,

    s_key: []const u8,

    n_rpm: u32,

    // the engine on/off button

    fn toggle(self: *DroneEngine) void {

        self.e_status = sw: switch (self.e_status) {

            EngineStatus.off => self.turn_on(),

            // if it’s on turn it off

            EngineStatus.on => {

                self.e_status = EngineStatus.off;

                self.n_rpm = 0;

                break :sw self.e_status;

            },

            EngineStatus.testing => EngineStatus.off,

            EngineStatus.autorepairing => EngineStatus.off,

            EngineStatus.failure => EngineStatus.failure,

        };

    }

    // function that checks whether the conditions

    // to start the engine are met

    fn turn_on(self: *DroneEngine) EngineStatus {

        if (self.n_health > DroneEngine.N_MIN_HEALTH) {

            // the engine turns on

            self.e_status = EngineStatus.on;

            self.n_rpm = DroneEngine.N_MAX_RPM * self.n_health / 100;

        } else if (self.n_health > 20) {

            // the engine attempts self-repair

            self.e_status = EngineStatus.autorepairing;

            self.n_rpm = DroneEngine.N_MAX_RPM * self.n_health / 100;

            DroneEngine.n_total_failed += 1;

        } else {

            // failure

            self.e_status = EngineStatus.failure;

            self.n_rpm = 0;

            DroneEngine.n_total_failed += 1;

        }

        return self.e_status;

    }

    // method that formats the struct and is invoked

    // automatically when we print it

    pub fn format(self: DroneEngine, writer: anytype) !void {

        try writer.print(

            \\Engine {s}:

            \\  * rpm: {}

            \\  * health: {}

            \\  * status: {s}

        , .{

            self.s_key,

            self.n_rpm,

            self.n_health,

            @tagName(self.e_status),

        });

    }

};

pub fn main() void {

    // all engines connected for the test

    var a_engines: [6]DroneEngine = .{

        DroneEngine{ .s_key = "E1", .n_health = 100, 

          .n_rpm = 0, .e_status = .off },

        DroneEngine{ .s_key = "E2", .n_health = 95, 

          .n_rpm = 0, .e_status = .off },

        DroneEngine{ .s_key = "E3", .n_health = 100,

          .n_rpm = 0, .e_status = .off },

        DroneEngine{ .s_key = "E4", .n_health = 98, 

          .n_rpm = 0, .e_status = .off },

        DroneEngine{ .s_key = "E5", .n_health = 60, 

          .n_rpm = 0, .e_status = .off },

        DroneEngine{ .s_key = "E6", .n_health = 0, 

          .n_rpm = 0, .e_status = .off },

    };

    // engine startup test

    for (&a_engines) |*o_engine| {

        if (o_engine.e_status == .off)

            o_engine.toggle();

        // using {f}, the format method we defined

        // will be used automatically

        print("{f}\n", .{o_engine});

    }

    print("\nThere have been {} failures\n", .{DroneEngine.n_total_failed});

}

$ zig run struct_engines.zig

Engine E1:

  * rpm: 8500

  * health: 100

  * status: on

Engine E2:

  * rpm: 8075

  * health: 95

  * status: on

Engine E3:

  * rpm: 8500

  * health: 100

  * status: on

Engine E4:

  * rpm: 8330

  * health: 98

  * status: on

Engine E5:

  * rpm: 5100

  * health: 60

  * status: autorepairing

Engine E6:

  * rpm: 0

  * health: 0

  * status: failure

There have been 2 failures

The player sits on the sand for a moment. He’s tired and covered in dust... his clothes dirty and torn. Escaping the caves, despite following a plan that involved tricking the tauroid trapped inside them and finding a way out using a modified algorithm stored in 1KR’s memory, had some tense moments.

- Very tense, he thinks.  It almost caught us.

- Now, after so many sleepless hours, he was feeling drowsy.

 - Alright, back to work. Let’s see…

Between the two disassembled ARP1 drones, there are six motors in total: one is completely broken, another is running halfway, and four work perfectly. They need to build a "wing" using those four motors. It has to be powerful enough to escape this prison along with 1KR.

The two ARP1s were a “gift,” like many others of the same model, produced in small batches in the inventor’s own workshop for the island’s ruler, a questioned leader, supposedly the son of a local deity.

Beliefs are like those clouds that pass in front of the sun. However massive they may seem, they’re just vapor and illusions in the light of truth. They go, and the sun remains.

Enums
Errors
© 2025 - 2026 Zen of Zig