Open5

Zigの知らなかった機能

smallkirbysmallkirby

Destructuring assignment みたいなやつ

fn hoge() struct { u64, u64 } {
    return .{ 1, 2 };
}
const a, const b = hoge();
smallkirbysmallkirby

Error Union の OR

const SomeError = error{ ErrorOne, ErrorTwo };
const SomeType = struct {
    const Error = error{ErrorThree};
};
inline fn hoge(s: anytype) (SomeError || @TypeOf(s).Error || error{ErrorFive})!void {
    return;
}
try hoge(SomeType{});
smallkirbysmallkirby

pub@import() した時以外は意味がない

同一ファイルで定義した構造体の関数は、たとえpub指定されていなくても呼び出すことができる:

const Hoge = struct {
    fn fuga() void {
        std.log.info("fuga", .{});
    }
};

test {
    Hoge.fuga(); // <= 可能
}
smallkirbysmallkirby

addrspace

per-CPU variable を実装する際に、以下のように FS-relative なポインタを生成できる:

const percpu_addrspace = std.builtin.AddressSpace.fs;

pub inline fn thisCpuGet(comptime pointer: anytype) *allowzero addrspace(percpu_addrspace) @typeInfo(@TypeOf(pointer)).Pointer.child {
    return @ptrFromInt(@intFromPtr(pointer) - @intFromPtr(&__per_cpu_start));
}

https://github.com/ziglang/zig/issues/653

利用する時はこんな感じ:

var some_variable: u32 linksection(".data..percpu") = 0xDEADBEEF;
thisCpuGet(&some_variable).* = 0xCAFEBABE;

実例:

https://github.com/smallkirby/norn/blob/a318b091ff378a7b44c6de41995d42d31dada25f/norn/percpu.zig#L63-L67