Structs
Structs are one way to define custom types in Zig:
const std = @import("std");
const print = std.debug.print;
const Color = struct {
red: f32,
green: f32,
blue: f32,
};
pub fn main() void {
var c = Color{
.red = 1.0,
.green = 0.0,
.blue = 1.0,
};
print("{} {} {}\n", .{ c.red, c.blue, c.green });
c.red = 0.5;
c.green = 0.25;
print("{}\n", .{c});
}$ zig run structs.zig
1 1 0
.{ .red = 0.5, .green = 0.25, .blue = 1 }
A struct definition can contain functions and constants:
const std = @import("std");
const print = std.debug.print;
const Color = struct {
red: f32,
green: f32,
blue: f32,
alpha: f32 = 1.0,
// An init function is often used as a constructor.
fn init(red: f32, green: f32, blue: f32) Color {
return .{
.red = red,
.green = green,
.blue = blue,
};
}
const WHITE = Color.init(0.0, 0.0, 0.0);
// Defining a method on Color:
fn isTransparent(self: Color) bool {
return self.alpha == 0.0;
}
fn makeTransparent(self: *Color) void {
self.alpha = 0.0;
}
};
pub fn main() void {
const w = Color.WHITE;
print("white: {}\n", .{w});
print("transparent? {}\n", .{
// Calling the method:
w.isTransparent()});
print("\n", .{});
var r = Color.init(1.0, 0.3, 0.3);
r.makeTransparent();
print("r: {}\n", .{r});
print("transparent? {}\n", .{r.isTransparent()});
print("\n", .{});
// With a pointer to a struct, we can still access
// fields and methods with .
const ptr = &r;
print("green: {}\n", .{ptr.green});
print("transparent?: {}\n", .{ptr.isTransparent()});
}$ zig run structs-2.zig
white: .{ .red = 0, .green = 0, .blue = 0, .alpha = 1 }
transparent? false
r: .{ .red = 1, .green = 0.3, .blue = 0.3, .alpha = 0 }
transparent? true
green: 0.3
transparent?: true
Next example: Tuples.