Zig Comptime Data Structures
A comptime data structure is a collection whose shape is fixed while the program is being compiled. Its fields and entries are known at compile time, so code can walk them without running a loop at run time.
Summing Struct Fields
This program walks every field of a struct and adds the values. The fields hold 1, 2, and 3.
const std = @import("std");
const S = struct { a: i32, b: i32, c: i32 };
pub fn main() !void {
const out = std.io.getStdOut().writer();
const s = S{ .a = 1, .b = 2, .c = 3 };
var sum: i32 = 0;
inline for (@typeInfo(S).@"struct".fields) |field| {
sum += @field(s, field.name);
}
try out.print("{}\n", .{sum});
}Summing Type Sizes
This program walks a comptime list of three types. It adds their sizes in bytes.
const std = @import("std");
pub fn main() !void {
const out = std.io.getStdOut().writer();
var total: usize = 0;
inline for ([_]type{ u32, i32, u8 }) |T| {
total += @sizeOf(T);
}
try out.print("{}\n", .{total});
}Printing Every Value
This program walks a comptime list of numbers. It prints each number on its own line.
const std = @import("std");
pub fn main() !void {
const out = std.io.getStdOut().writer();
inline for ([_]i32{ 2, 4, 6 }) |v| {
try out.print("{}\n", .{v});
}
}Example
const std = @import("std");
const S1 = struct { a: i32, b: i32 };
const S2 = struct { a: i32, b: i32, c: i32 };
fn sumFields(s: anytype) i32 {
var sum: i32 = 0;
inline for (@typeInfo(@TypeOf(s)).@"struct".fields) |field| {
sum += @field(s, field.name);
}
return sum;
}
pub fn main() !void {
const out = std.io.getStdOut().writer();
const s1 = S1{ .a = 1, .b = 2 };
const s2 = S2{ .a = 10, .b = 20, .c = 30 };
try out.print("{} {}\n", .{ sumFields(s1), sumFields(s2) });
}Key points
- Comptime data structure: a comptime data structure is a collection whose entries are known at compile time.
- Inline for: inline for is a loop that is unrolled at compile time, one copy of its body per entry.
- An unrolled loop: an unrolled loop is a loop whose body is repeated once for each entry at compile time.
- A struct field list can be walked with inline for, so one body can handle every field.
- A comptime list of types can be walked the same way, with one step per type.
- Because the entries are known early, a mistake in an entry is caught at compile time.
The helper walks the fields of any struct with integer fields. It adds each field value to a running total. The main function prints the total for two different structs.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
What does inline for do with its body?