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 / Method | Description |
|---|---|
const T = struct { ... }; | Defines a struct type by declaring a set of fields and their types. |
field_name: Type = value | Defines 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.field | Accesses a field of a struct instance. |
pub fn method(self: T) Type | Defines an immutable method on the struct. self allows read-only access to the instance's fields. |
pub fn method(self: *T) void | Defines 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: Type | Defines 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 contact us.