Generic Types
Generic functions are fun, let’s try generic data types next!
We’ll create a type that limits values to a certain range. It should work for any number type.
const std = @import("std");
const print = std.debug.print;
const LimitError = error{
OutOfRange,
};
// Limited is a function that returns a type.
fn Limited(T: type, min: T, max: T) type {
return struct {
// @This is the type we’re currently defining.
const Self = @This();
value: T,
fn init(value: T) !Self {
var r: Self = undefined;
try r.set(value);
return r;
}
fn get(self: Self) T {
return self.value;
}
fn set(self: *Self, value: T) !void {
if (value < min or value > max)
return LimitError.OutOfRange;
self.value = value;
}
};
}
pub fn main() !void {
var l = try Limited(u64, 0, 100).init(5);
print("l is a {s}\n", .{@typeName(@TypeOf(l))});
print("l is {}\n", .{l.get()});
try l.set(50);
print("l is {}\n", .{l.get()});
l.set(500) catch {
print("got error!\n", .{});
};
}$ zig run limited.zig
l is a limited.Limited(u64,0,100)
l is 5
l is 50
got error!
Next example: Reflection.