Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

  1. Home
  2. Zig Dictionary
  3. struct Basics

struct Basics

In Zig, you can use struct to define a custom data type that groups multiple fields together. In addition to fields, a struct can have methods and constants, enabling object-oriented-style data management.

Syntax

// -----------------------------------------------
// struct — defining a struct type
// -----------------------------------------------

const TypeName = struct {
    field_name: Type,           // field definition
    field_name: Type = default, // field definition with a default value
};

// -----------------------------------------------
// Creating an instance of a struct
// -----------------------------------------------

// Create an instance by specifying all fields
const instance = TypeName{
    .field_name = value,
    .field_name = value,
};

// -----------------------------------------------
// Defining methods (attaching functions to a struct)
// -----------------------------------------------

const TypeName = struct {
    field_name: Type,

    // Using self as the first parameter makes this callable as a method
    pub fn methodName(self: TypeName) ReturnType {
        return self.field_name;
    }

    // A method that mutates the struct receives *TypeName (a pointer)
    pub fn mutableMethodName(self: *TypeName, new_value: Type) void {
        self.field_name = new_value;
    }
};

// Calling a method
const result = instance.methodName();

Syntax Reference

Syntax / MethodDescription
const T = struct { ... };Defines a struct type by declaring a set of fields and their types.
field_name: Type = valueDefines a field with a default value. The field can be omitted when creating an instance.
T{ .field = value }Creates an instance of the struct. All fields without default values must be specified.
instance.fieldAccesses a field of a struct instance.
pub fn method(self: T) TypeDefines an immutable method on the struct. self allows read-only access to the instance's fields.
pub fn method(self: *T) voidDefines a mutable method on the struct. self.* allows the instance's fields to be modified.
instance.method()Calls a method on a struct instance. self is passed automatically.
T{ .field = value, ._ = undefined }Initializes some fields with undefined (used when omitting fields that have no default value).
comptime field_name: TypeDefines a field that is used only at compile time.

Sample Code

jujutsu_struct.zig
// jujutsu_struct.zig — demonstrates Zig struct field definitions,
// initialization, and methods using Jujutsu Kaisen characters

// Import the standard library
const std = @import("std");

// -----------------------------------------------
// Sorcerer struct — defines a type representing a sorcerer
// -----------------------------------------------
const Sorcerer = struct {
    name: []const u8,      // sorcerer's name
    grade: u8,             // grade (lower number means higher rank)
    cursed_energy: u32,    // amount of cursed energy
    is_special: bool = false, // whether special grade (false by default)

    // -----------------------------------------------
    // grade_label method — returns the grade as a string
    // self is an immutable reference; only reads fields
    // -----------------------------------------------
    pub fn grade_label(self: Sorcerer) []const u8 {
        if (self.is_special) return "Special Grade";
        return switch (self.grade) {
            1 => "Grade 1",
            2 => "Grade 2",
            3 => "Grade 3",
            4 => "Grade 4",
            else => "Unknown",
        };
    }

    // -----------------------------------------------
    // power_up method — increases cursed energy
    // Receives self as *Sorcerer (pointer) to allow field mutation
    // -----------------------------------------------
    pub fn power_up(self: *Sorcerer, amount: u32) void {
        self.cursed_energy += amount;
    }

    // -----------------------------------------------
    // describe method — prints character information
    // -----------------------------------------------
    pub fn describe(self: Sorcerer, writer: anytype) !void {
        try writer.print("  [{s}] {s} — Cursed Energy: {d}\n", .{
            self.grade_label(),
            self.name,
            self.cursed_energy,
        });
    }
};

// -----------------------------------------------
// TechniqueDomain struct — defines a type representing a technique and domain
// -----------------------------------------------
const TechniqueDomain = struct {
    sorcerer_name: []const u8,  // name of the user
    technique: []const u8,      // technique name
    domain: ?[]const u8 = null, // domain expansion name (null if not mastered)

    // has_domain method — returns whether the sorcerer has a domain expansion
    pub fn has_domain(self: TechniqueDomain) bool {
        return self.domain != null;
    }
};

pub fn main() !void {
    // Get a writer for standard output
    const stdout = std.io.getStdOut().writer();

    try stdout.print("=== Jujutsu Kaisen Sorcerer Database ===\n\n", .{});

    // -----------------------------------------------
    // Create instances of Sorcerer
    // Specify each field using the .field_name = value syntax
    // -----------------------------------------------
    var gojo = Sorcerer{
        .name = "Gojo Satoru",
        .grade = 1,
        .cursed_energy = 100000,
        .is_special = true,  // special grade sorcerer
    };

    var yuji = Sorcerer{
        .name = "Itadori Yuji",
        .grade = 1,
        .cursed_energy = 85000,
    };

    var megumi = Sorcerer{
        .name = "Fushiguro Megumi",
        .grade = 2,
        .cursed_energy = 70000,
    };

    var nobara = Sorcerer{
        .name = "Kugisaki Nobara",
        .grade = 3,
        .cursed_energy = 60000,
    };

    var nanami = Sorcerer{
        .name = "Nanami Kento",
        .grade = 1,
        .cursed_energy = 80000,
    };

    // -----------------------------------------------
    // Display character info using the describe() method
    // -----------------------------------------------
    try stdout.print("--- Sorcerer List ---\n", .{});
    try gojo.describe(stdout);
    try yuji.describe(stdout);
    try megumi.describe(stdout);
    try nobara.describe(stdout);
    try nanami.describe(stdout);

    // -----------------------------------------------
    // Modify fields using the power_up() method
    // Mutable methods use pointer passing, so variables must be declared with var
    // -----------------------------------------------
    try stdout.print("\n--- Cursed Energy After Training ---\n", .{});
    yuji.power_up(15000);
    megumi.power_up(20000);
    nobara.power_up(10000);

    try yuji.describe(stdout);
    try megumi.describe(stdout);
    try nobara.describe(stdout);

    // -----------------------------------------------
    // Create instances of TechniqueDomain
    // domain is optional (defaults to null)
    // -----------------------------------------------
    try stdout.print("\n--- Techniques and Domain Expansions ---\n", .{});

    const techniques = [_]TechniqueDomain{
        .{ .sorcerer_name = "Gojo Satoru",    .technique = "Limitless",              .domain = "Infinite Void" },
        .{ .sorcerer_name = "Itadori Yuji",   .technique = "Divergent Fist",         .domain = null },
        .{ .sorcerer_name = "Fushiguro Megumi", .technique = "Ten Shadows Technique", .domain = "Chimera Shadow Garden" },
        .{ .sorcerer_name = "Kugisaki Nobara", .technique = "Straw Doll Technique",  .domain = null },
        .{ .sorcerer_name = "Nanami Kento",   .technique = "Ratio Technique",        .domain = null },
    };

    // Process each element of the array with a for loop
    for (techniques) |td| {
        if (td.has_domain()) {
            // domain is of type ?[]const u8 (optional), so unwrap it with .?
            try stdout.print("  {s}: {s} / Domain: {s}\n", .{
                td.sorcerer_name,
                td.technique,
                td.domain.?,
            });
        } else {
            try stdout.print("  {s}: {s} / Domain: Not mastered\n", .{
                td.sorcerer_name,
                td.technique,
            });
        }
    }

    // Verify direct field access
    try stdout.print("\n--- Gojo's Final Stats ---\n", .{});
    try stdout.print("  Cursed Energy: {d}\n", .{gojo.cursed_energy});
    try stdout.print("  Grade Label: {s}\n", .{gojo.grade_label()});
}
zig run jujutsu_struct.zig
=== Jujutsu Kaisen Sorcerer Database ===

--- Sorcerer List ---
  [Special Grade] Gojo Satoru — Cursed Energy: 100000
  [Grade 1] Itadori Yuji — Cursed Energy: 85000
  [Grade 2] Fushiguro Megumi — Cursed Energy: 70000
  [Grade 3] Kugisaki Nobara — Cursed Energy: 60000
  [Grade 1] Nanami Kento — Cursed Energy: 80000

--- Cursed Energy After Training ---
  [Grade 1] Itadori Yuji — Cursed Energy: 100000
  [Grade 2] Fushiguro Megumi — Cursed Energy: 90000
  [Grade 3] Kugisaki Nobara — Cursed Energy: 70000

--- Techniques and Domain Expansions ---
  Gojo Satoru: Limitless / Domain: Infinite Void
  Itadori Yuji: Divergent Fist / Domain: Not mastered
  Fushiguro Megumi: Ten Shadows Technique / Domain: Chimera Shadow Garden
  Kugisaki Nobara: Straw Doll Technique / Domain: Not mastered
  Nanami Kento: Ratio Technique / Domain: Not mastered

--- Gojo's Final Stats ---
  Cursed Energy: 100000
  Grade Label: Special Grade

Overview

A Zig struct is a composite data type that groups multiple fields together. Each field must have an explicit type, and default values can be provided. To create an instance, use the TypeName{ .field_name = value } syntax and specify all fields that have no default value.

Methods can be defined on a struct. When the first parameter is self: TypeName (passed by value), the method is read-only. When it is self: *TypeName (passed by pointer), the method can mutate the struct's fields. To call a mutable method like power_up() in the sample, the instance must be declared with var. Optional-type fields (?Type) allow a field to represent the absence of a value. See also enum (enumeration types) and error handling.

If you find any errors or copyright issues, please .