zig入門する
ミーハーなので、Zig言語に入門して見たくなった
zlsという言語サーバーを入れておくと、テキストエディタで補完が効くらしいので
とりあえずDLした
tar.xz形式がLhpaplusで対応していなかったので、7-zipで解凍した
zlsのパス通したけど、なぜかvscodeで補完されない
言語サーバー自体は立ち上がってるっぽい
コンパイラエラーも表示してくれる
とりあえずこれを見ていきます
こんな感じのコードをzig test main.zig
って感じでいじってる
標準出力の仕方がイマイチ理解できていないので
const std = @import("std");
const expect = @import("std").testing.expect;
test "main" {
const num: i32 = 5;
try expect(num == 5);
const arr = [_]u8{ 'h', 'o', 'g', 'e' };
try expect(arr.len == 4);
}
test "if" {
const a = true;
var x: i32 = 1;
if (a) {
x += 1;
}
try expect(x == 2);
var b: i32 = undefined;
b = if (a) 1 else 2;
try expect(b == 1);
}
test "loop" {
var sum: i32 = 0;
var i: i32 = 0;
while (i <= 10) : (i += 1) {
sum += i;
}
try expect(sum == 55);
}
日を跨いでswitchから開始
switch、パターンマッチっぽい構文なんだな
C#のswitch式みたいなノリなので馴染みやすい
match式みたいな感じじゃないんだな
test "switch" {
var x: i8 = 10;
x = switch (x) {
-1...1 => -x,
10, 100 => @divExact(x, 2),
else => x,
};
try expect(x == 5);
}
runtime safety
配列のout of rangeの例
test "out of bounds" {
const a = [3]u8{ 1, 2, 3 };
var index: u8 = 5;
const b = a[index];
_ = b;
}
Rustみたいにコンパイルエラーにはならないけど、
ちゃんとランタイムでパニックしてる
ここで重要なのは、C言語みたいに変なメモリ領域へ突っ込むことがないということ、かな
❯ zig test .\main.zig
Test [5/5] test "out of bounds"... thread 24128 panic: index out of bounds
D:\kaitoFolder\programs\zig-practice\main.zig:52:16: 0x7ff74f5d1b3b in est "out of bounds" (test.obj)
const b = a[index];
^
unreachable
コンパイラに到達不可能な文であることを伝える
当然到達した時にはランタイムエラーになるっぽい
こういう構文をちゃんと使うことによって最適化につながるのかな
あとzig、未使用な変数があった場合にコンパイルできない
これはなんかの設定なのかしら
ポインタ。
結構Cとかのポインタと手触りは似ている
0ポインタは許容されない(ランタイムでエラー)
fn increaments(num: *u8) void {
num.* += 1;
}
test "pointers" {
var x: u8 = 1;
increaments(&x);
try expect(x == 2);
// pointer not allowed 0
// var n: u16 = 0;
// var y: *u8 = @intToPtr(*u8, n);
// _ = y;
}
slice
うん。って感じ
いい意味でCらしさがなくて良い
test "slices" {
const arr = [_]u8{ 1, 2, 3, 4 };
const slice = arr[0..3];
try expect(slice.len == 3);
var sum: u8 = 0;
for (slice) |v| sum += v;
try expect(sum == 6);
try expect(@TypeOf(slice) == *const [3]u8);
}
enum
関数も中に書けるんだな
const Direction = enum { north, south, east, west };
const Values = enum(u32) {
hundread = 100,
thousand = 1000,
million = 1000000,
next,
pub fn isHundread(self: Values) bool {
return self == Values.hundread;
}
};
test "enum" {
try expect(@enumToInt(Values.hundread) == 100);
try expect(Values.isHundread(Values.hundread));
}
構造体も見た
まぁ普通だなぁという感想だったので写経して終わり
ここまでわかればまぁ簡単なプログラムが書けるかなぁと思ったので
細かく見るのは終了
個人的にはoptionalとか書き心地が良さそう
comptimeの説明が長くて読んでないけど、なんか重要そう