the standard library
- std.math is surprisingly rich
- std.fs is surprisingly robust, using file operations with reference to a directory as the 'default'.
defer
- as an alternative to RAII
- simple contract programming
- statically enforcing the absence of errors:
errdefer comptime unreachable - logging errors:
errdefer
inline
inline in Zig is not a semantically neutral hint: it always takes effect, and it has semantic meaning.
- it seems like inline functions can allocate on the caller's stack:
const std = @import("std"); const Point = struct { x: i32, y: i32 }; /// returned pointer is to an object on the caller's stack. inline fn f(n: i32) *const Point { return &.{ .x = n, .y = n }; } /// returned pointer is to an object on g()'s stack during the call to g(), /// which becomes invalid after it returns. fn g(n: i32) *const Point { return &.{ .x = n, .y = n }; } test f { const p1 = f(2); const p2: Point = .{ .x = 0, .y = 0 }; const p3 = f(4); var p4: Point = undefined; p4.x = p1.x; p4.y = p2.y + p3.y; std.debug.print("{}\n", .{p1}); std.debug.print("{}\n", .{p2}); std.debug.print("{}\n", .{p3}); std.debug.print("{}\n", .{p4}); } test g { const p1 = g(2); const p2: Point = .{ .x = 0, .y = 0 }; const p3 = g(4); var p4: Point = undefined; p4.x = p1.x; p4.y = p2.y + p3.y; std.debug.print("{}\n", .{p1}); std.debug.print("{}\n", .{p2}); std.debug.print("{}\n", .{p3}); std.debug.print("{}\n", .{p4}); } - inline loops can expand over disparate types:
test "what type is x?" { inline for (&.{ 1, true, "a string", .{ 0, 5 } }) |x| { @compileLog(@TypeOf(x)); } }Compile Log Output: @as(type, comptime_int) @as(type, bool) @as(type, *const [8:0]u8) @as(type, struct{comptime comptime_int = 0, comptime comptime_int = 5}) - something I don't quite get: you can inline a stub to prevent more involved codegen: discord reference.
- inline functions can detect if a parameter is comptime-known:
const std = @import("std"); inline fn comptime_known(x: anytype) bool { // 0.14.0-dev.2034 return @typeInfo(@TypeOf(.{x})).@"struct".fields[0].is_comptime; } test { try std.testing.expectEqual(true, comptime_known(1)); const x: i32 = 1; try std.testing.expectEqual(true, comptime_known(x)); try std.testing.expectEqual(false, comptime_known(std.time.timestamp())); }