🎓 A1Learner
🔍
0 of 46 lessons completed

Zig Type Introspection

Type introspection is examining a type at compile time to learn its shape. It lets one program handle different types by asking what each type contains.

Integer shape

Type info for u32 reports its bit count and its signedness, and the same check on i16 shows a signed result.

const std = @import("std");
pub fn main() !void {
    const out = std.io.getStdOut().writer();
    const info = @typeInfo(u32);
    const info2 = @typeInfo(i16);
    try out.print("bits={d} signed={s}\n", .{ info.int.bits, @tagName(info.int.signedness) });
    try out.print("bits={d} signed={s}\n", .{ info2.int.bits, @tagName(info2.int.signedness) });
}

Struct fields

Type info for a struct lists its fields in order, with each field name available at compile time.

const std = @import("std");
pub fn main() !void {
    const out = std.io.getStdOut().writer();
    const Point = struct { x: i32, y: i32 };
    const sinfo = @typeInfo(Point);
    try out.print("fields={d}\n", .{sinfo.@"struct".fields.len});
    try out.print("first={s}\n", .{sinfo.@"struct".fields[0].name});
    try out.print("second={s}\n", .{sinfo.@"struct".fields[1].name});
}

Kind by tag

The tag of type info tells which kind a type is, so a switch can choose a word for each kind.

const std = @import("std");
pub fn main() !void {
    const out = std.io.getStdOut().writer();
    const a = switch (@typeInfo(i32)) { .int => "integer", .float => "float", .bool => "boolean", else => "other" };
    const b = switch (@typeInfo(f64)) { .int => "integer", .float => "float", .bool => "boolean", else => "other" };
    try out.print("{s}\n{s}\n", .{ a, b });
}

Example

const std = @import("std");
pub fn main() !void {
    const out = std.io.getStdOut().writer();
    const Point = struct { x: i32, y: i32 };
    const sinfo = @typeInfo(Point);
    const Color = enum { red, green, blue };
    const einfo = @typeInfo(Color);
    try out.print("struct-fields={d}\n", .{sinfo.@"struct".fields.len});
    try out.print("x-type={s}\n", .{@typeName(sinfo.@"struct".fields[0].type)});
    try out.print("y-type={s}\n", .{@typeName(sinfo.@"struct".fields[1].type)});
    try out.print("enum-fields={d}\n", .{einfo.@"enum".fields.len});
    try out.print("first-choice={s}\n", .{einfo.@"enum".fields[0].name});
}

Key points

  • Type info: type info is the description that @typeInfo returns for a type.
  • Signedness: signedness is whether an integer type can hold negative values.
  • Field: a field is a named value inside a struct.
  • Field list: a field list is the ordered list of fields that type info gives for a struct.
  • Tag: a tag is the name that tells which kind a type is, such as int or float.
  • Enum field: an enum field is one named choice inside an enum.

The code asks type info for a struct and an enum. It reads the field count and the type of each struct field. It also reads the enum field count and the name of its first choice.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

What does @typeInfo(u32) describe?