ジグをやったことがありますか.


こんにちはZig :リジーブバッファを通してZigを探検してください



ジグには本当にクールなものがたくさんあります.
  • 小さな言語:脳で多くのものを持っていない
  • ポインタとメモリの安全性
  • マルチホーム
  • 初期のプロジェクトのすべてが行われる
  • DEPS


    zigをインストールしますhttps://ziglang.org/download/
    vimにzigをインストールしますhttps://github.com/ziglang/zig.vim

    開始


    こんにちは世界を言いましょう
    const std = @import("std");
    
    
    pub fn main() void {
        // WRONG on purpose
        std.debug.print("hello, world !\n");
    }
    
    ここで間違っているstd.debug.print つの引数をとりますので、基本的なHello Worldは
    const std = @import("std");
    
    
    pub fn main() void {
        std.debug.print("hello, world !\n", .{});
    }
    
    最初は変に見えます.
    そこでは、Zigは誇大宣伝言語ではないことがわかります:最初の機能の選択肢から作られている.

    doc世代


    まだ準備ができていない.
    オートドキュメントが進行中です.https://github.com/tiehuis/zig-docgen

    基本的なIO /バッファを行う


    単純なasynio io/bufferでzigを試してみましょう.
    ゴールは、CHARによってasync charを書きます.

    ステップ1 alloc


    必要なもの

    店舗データ


    struct :https://ziglang.org/documentation/master/#struct

    アロケータ


    メモリhttps://ziglang.org/documentation/master/#memory
    注意:最初はポインタの算術演算を使います.しかし、スライスは、言語のポインタの算術演算で強制されます!
    https://github.com/ziglang/zig/issues/45

    スライス


    スライスはGolang 1より非常によく似た構文に従います.
    // write a slice
    const slice: []const u8 = "hello slice";
    // write an array
    const array: [11]u8 = "hello array".*;
    
    参照:https://ziglang.org/documentation/master/#Slices

    試験結果


    どこだzig docを読まなければなりません.
    小さなallocサンプルを作ります
  • スライスをalloc
  • 書き込みスライス
  • フリースライス
  • ここでZigは良いテスト機能を持っています.
    それを使いましょう.参照https://ziglang.org/documentation/master/#Zig-Test
    const std = @import("std");
    const Allocator = std.mem.Allocator;
    const Gpa = std.heap.GeneralPurposeAllocator;
    
    test "try to allocate memory" {
        // create a general pupose allocator
        var gpa = Gpa(.{ .enable_memory_limit = true }){};
        // get a reference the instance of the allocator
        var allocator = &gpa.allocator;
        // check that no memory has been requested
        std.testing.expect(gpa.total_requested_bytes == 0);
    
        // allocate some memory (not the try)
        const ptr = try allocator.alloc(u8,10);
    
        // check that the allocation success
        std.testing.expect(gpa.total_requested_bytes == 10);
    
        // free memory
        allocator.free(ptr);
    
        // check free success
        std.testing.expect(gpa.total_requested_bytes == 0);
    
    }
    
    テストを実行する
    zig test alloc.zig
    

    ステップ2:同期LIFO


    割り当てがクリアされました.さあ、バッファーに戻りましょう.
    多くのZig機能は多分概念を使用します.
    来たるべきfronMaybe monad Haskellで他の言語に適応.
    例えば、std:optionnal CPPで.
    これは、関数がエラーを成功または復帰したことを示します.ErrorType!ReturnTypeこれはエラー処理の非常にエレガントな方法であり、他の言語問題を避けることです.
  • エラーチェックがGolang(1.13から改善される)ならば.
  • Pythonでの例外処理(ここでは改良されません).
  • 参照https://ziglang.org/documentation/master/#Errors

    コード


    4つの関数を書きます:
    インプット
    fn init(size: u32, a: *Allocator) Error!*Buff {
    
    執筆
    fn write(b: *Buff, c: u8) void {
    
    読める
    fn read(b: *Buff) u8 {
    
    クローズ
    fn close(b: *Buff) void {
    
    プログラム:
    const std = @import("std");
    const Allocator = std.mem.Allocator;
    const GPA = std.heap.GeneralPurposeAllocator;
    const Error = std.mem.Allocator.Error;
    
    /// Buff struct
    /// size the size of the buffer
    /// addr the address of the undelying memory block
    /// offset the first unused place in the buffer 0xffff means the buff is full
    /// allocator the address of the us allocator
    const Buff = struct {
        size: u32,
        addr: []u8,
        offset: u32,
        allocator: *Allocator,
    };
    
    /// init a buffer of the deisred size
    fn init(size: u32, a: *Allocator) Error!*Buff {
    
        var ptr = try a.alloc(u8, size);
        return &Buff{
            .size = size,
            .addr = ptr,
            .offset = 0,
            .allocator = a,
        };
    }
    
    /// close the given buffer and free it's memory
    fn close(b: *Buff) void {
        b.allocator.free(b.addr);
    }
    
    /// write c into our buffer
    fn write(b: *Buff, c: u8) void {
        // todo add fail if more than size
        b.addr[b.offset] = c;
        b.*.offset += 1;
    }
    
    /// read c into our buffer
    fn read(b: *Buff) u8 {
        b.offset -= 1;
        // todo add fail if 0
        const c: u8 = b.addr[b.offset];
        return c;
    }
    
    pub fn main() !void {
        var gpa = GPA(.{}){};
        var alloc = &gpa.allocator;
    
        var buff = try init(3, alloc);
        defer close(buff);
    
        std.debug.print("writing 'a' to buff\n", .{});
        write(buff, 'a');
    
    
        std.debug.print("reading one char from buff\n", .{});
        const c = read(buff);
        std.debug.print("char is : {c}\n", .{c});
    
    
        std.debug.print("writing 'a' then 'b' to buff\n", .{});
        write(buff, 'a');
        write(buff, 'b');
    
    
    
        std.debug.print("reading two char from buff\n", .{});
        const d = read(buff);
        const e = read(buff);
        std.debug.print("chars are : {c} {c}\n", .{d, e});
    
        // test failure uncomment next line : overflow
        // const f = read(buff);
    
        // test failure uncomment next line : out of bound
        // write(buff, '1'); write(buff, '2'); write(buff, '3'); write(buff, '4');
    
    }
    

    テストする


    zig run sync_buff.zig
    
    出力
    writing 'a' to buff
    reading one char from buff
    char is : a
    writing 'a' then 'b' to buff
    reading two char from buff
    chars are : b a
    

    安全


    そこにない値を読みましょう.
    SyncSum BUFFのオーバーフローエラーを解除します.ジグ
    zig run sync_buff.zig
    
    エラー
    thread 34197 panic: integer overflow
    /home/pierrot/dev/helloZig/sync_buff.zig:44:14: 0x2363d1 in read (sync_buff)
        b.offset -= 1;
                 ^
    /home/pierrot/dev/helloZig/sync_buff.zig:78:19: 0x22ddb4 in main (sync_buff)
        const f = read(buff);
                      ^
    /home/pierrot/.zig/lib/std/start.zig:345:37: 0x205684 in std.start.posixCallMainAndExit (sync_buff)
                const result = root.main() catch |err| {
                                        ^
    /home/pierrot/.zig/lib/std/start.zig:163:5: 0x205522 in std.start._start (sync_buff)
        @call(.{ .modifier = .never_inline }, posixCallMainAndExit, .{});
        ^
    Aborted (core dumped)
    
    そこにない値を読みましょう.
    SyncChort BUFFのうち、除外されたエラーをコメントしない.ジグ
    zig run sync_buff.zig
    
    エラー
    thread 35402 panic: index out of bounds
    /home/pierrot/dev/helloZig/sync_buff.zig:38:11: 0x2362a9 in write (sync_buff)
        b.addr[b.offset] = c;
              ^
    /home/pierrot/dev/helloZig/sync_buff.zig:83:64: 0x22ddec in main (sync_buff)
        write(buff, '1'); write(buff, '2'); write(buff, '3'); write(buff, '4');
                                                                   ^
    /home/pierrot/.zig/lib/std/start.zig:345:37: 0x205684 in std.start.posixCallMainAndExit (sync_buff)
                const result = root.main() catch |err| {
                                        ^
    /home/pierrot/.zig/lib/std/start.zig:163:5: 0x205522 in std.start._start (sync_buff)
        @call(.{ .modifier = .never_inline }, posixCallMainAndExit, .{});
        ^
    Aborted (core dumped)
    

    サンプル


    すべてのコードサンプルはここで入手できます.https://github.com/pmalhaire/helloZig .

    結論


    Zigは経験豊かな開発者のためのdefinetlyシンプルです.それは単純なマナー複雑な概念で公開します.
    それはあなたのツールボックスに持っている非常に良い言語です.それは、おそらく来るべき年に速く成長します.