ジグをやったことがありますか.
こんにちは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サンプルを作ります
それを使いましょう.参照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機能は多分概念を使用します.
来たるべきfron
Maybe monad
Haskellで他の言語に適応.例えば、
std:optionnal
CPPで.これは、関数がエラーを成功または復帰したことを示します.
ErrorType!ReturnType
これはエラー処理の非常にエレガントな方法であり、他の言語問題を避けることです.コード
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シンプルです.それは単純なマナー複雑な概念で公開します.
それはあなたのツールボックスに持っている非常に良い言語です.それは、おそらく来るべき年に速く成長します.
Reference
この問題について(ジグをやったことがありますか.), 我々は、より多くの情報をここで見つけました https://dev.to/pmalhaire/ziglang-first-contact-with-memory-safety-and-simplicity-83pテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol