Open7

Zigの不満点

smallkirbysmallkirby

string([]const u8)でswitchできない

'std.mem.eql'と大量のifでやるしかない。文字列比較の方法的に仕方ないんだろうけど、せめてmem.eqlのシンタックスシュガーとしてswitchでできるようにしてほしい

ktz_aliasktz_alias

比較対象が静的に分かってる場合限定ですが、std.mem.eqlを書くのがクソだるい場合に、std.ComptimeStringMapstd.StaticStringMapをよく使います。
↑今は名前変わってたわ。うっかりうっかり。

そのままルックアップするもよし、comptimeで文字列リテラルを引数に取りenumを返す関数を用意してswitchで分岐するもよし。

comptimeで文字列リテラルを引数に取りenumを返す関数は、F#Active Patternに着想を得ています。

smallkirbysmallkirby

構造体のプライベートフィールド

ファイル単位(std.mem.Allocatorとか)ならできるよね?まぁプライベートを挿入した結果OOPがメインストリームになったら最悪だけど

ktz_aliasktz_alias

コンパイル時の型解決を許すのであればなんとか・・・。

fn PrivType(a: []const u8, b: u32) type {
    return struct {
        pub fn valA(self: @This()) []const u8 {
            _ = self;
            return a;
        }
        pub fn valB(self: @This()) u32 {
            _ = self;
            return b;
        }
    };
}

test "simple test" {
    const sa = "123";
    const sb = "456";

    const a1, const b1 = comptime blk:{
        const b = try std.fmt.parseInt(u32, sb, 0);

        const t: PrivType(sa, b) = .{};
        
        break :blk .{t.valA(), t.valB()};
    };

    std.debug.print("a: {s}, b: {}", .{a1, b1});
}
smallkirbysmallkirby

確かにgetterとして持たせることはできますね。
ただその方法だとインスタンスごとに関数が作られちゃって.textが肥大化するのと、何よりhackyでオーバーキルな感じがしちゃいますね... 💀

smallkirbysmallkirby

extern struct のフィールドが align(1) ではない

extern struct はフィールドの型に応じて勝手にパディングを入れる。
例えば u16 のフィールドは u16 アラインされるように1バイトのパディングを入れたりする。

自分の場合 extern struct を使うのは低レベルに定義されたデータ構造を表現する場合がほとんどだから、Cで言うところの __attribute__((packed)) がデフォルト動作であってほしい。
今のままだと、全てのフィールドに align(1) をつけるというアホほどめんどうなことをする必要がある。

Ref:

smallkirbysmallkirby

type が予約語

type を変数名に使いたいことがしばしばある。
Type とかにしてくれ。