Closed18

zig入門する

にー兄さんにー兄さん

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));
}

このスクラップは2022/07/18にクローズされました