🎓 A1Learner
🔍
0 of 55 lessons completed

Zig Comptime Parameters

A comptime parameter is an argument Zig works out while the program is still compiling. Passing a type as a comptime parameter lets one function work with several types of number.

One function doubles an integer

Twice takes a type T and a value of that type. Here T is i32 and the value is 21.

const std = @import("std");

fn twice(comptime T: type, value: T) T {
    return value + value;
}

pub fn main() !void {
    const out = std.io.getStdOut().writer();
    try out.print("{d}\n", .{twice(i32, 21)});
}

The same function doubles a float

Nothing in twice changes for a new type. Only the arguments at the call change.

const std = @import("std");

fn twice(comptime T: type, value: T) T {
    return value + value;
}

pub fn main() !void {
    const out = std.io.getStdOut().writer();
    try out.print("{d}\n", .{twice(i32, 7)});
    try out.print("{d}\n", .{twice(f64, 1.5)});
}

Add one to two different types

AddOne works the same way with a u8 and with an i64. Each result keeps the type that was passed in.

const std = @import("std");

fn addOne(comptime T: type, value: T) T {
    return value + 1;
}

pub fn main() !void {
    const out = std.io.getStdOut().writer();
    try out.print("{d} {d}\n", .{ addOne(u8, 41), addOne(i64, -5) });
}

Example

const std = @import("std");

fn scale(comptime T: type, value: T, factor: T) T {
    return value * factor;
}

pub fn main() !void {
    const out = std.io.getStdOut().writer();
    try out.print("{d}\n", .{scale(i32, 6, 3)});
    try out.print("{d}\n", .{scale(f64, 2.5, 4)});
}

Key points

  • Comptime: work Zig does at compile time, before the program runs.
  • Type parameter: writing comptime T: type makes T a parameter that receives a type, such as i32 or f64.
  • Value parameter: a second parameter written with the type T holds a real value of that type.
  • One function, many types: the same body is checked and used for each type it is called with.
  • Call: the type is passed like an ordinary argument, as in twice(i32, 21).

In this example, scale takes a type T, then a value and a factor, both of type T. The first call uses i32, so 6 times 3 gives 18. The second call uses f64, so 2.5 times 4 gives 10, printed as a whole number.

Note

the type must be known at compile time, so it can never come from a value read while the program runs.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

In `fn twice(comptime T: type, value: T) T`, what is passed for T at a call?