Zig 入門 #1 - 代入、配列

2022-04-10  /  ZigProgramming

ziglearn.org を参考に Zig の基本を一通りさらってみます。まずは Chapter 1 - Basics | ziglearn.org から。代入と配列について確認しました。

代入

参考: Assignment

以下のように記述します。

(const | var) identifier[: type] = value;

代入については他の言語でもなじみがあるので難しい気はしません。

試したコードは以下の通りです。

    const constant: i32 = 5; // 定数
    var variable: u32 = 5000; // 変数

    std.log.info("constant {}, variable {}", .{ constant, variable });

    // 変数なので再代入可能
    variable = 10000;
    std.log.info("variable can be changed {}", .{variable});

    // @as(type, value) で代入することもできる
    const inferred_constant = @as(i32, 5);
    var inferred_variable = @as(u32, 5000);

    std.log.info("inferred, constant {}, variable {}", .{ inferred_constant, inferred_variable });

    // 型推論される場合 type は省略可能
    var inferred = variable;
    std.log.info("inferred variable {}", .{inferred});

    // typeを指定している場合には `undefined` を代入することが可能
    var a: i32 = undefined;
    std.log.info("a {}", .{a}); // 何かしらの値にはなるっぽい

    // 未使用の変数はコンパイルエラーになる
    // var unused: i32 = 0;
    // src/main.zig:24:9: error: unused local variable
    //     var unused: i32 = 0;
    //         ^

今の時点でわからないのは、以下の点です。

配列

参考: Arrays

Arrays を配列と言い切って良いのか自信はありませんがひとまず配列とします。配列の型の記述は以下です。

[length]type

配列のリテラルは以下のように書きます。

[length]type{elmentA, elmentB, ...}

配列の要素数をリテラルの要素数とする、という仕様自体は珍しいものではないと思いますが、省略できず []type と書けないのが自分は珍しく感じました。

試したコードは以下の通りです。

    // a の type は配列リテラルから推論される
    const a = [5]u8{ 'h', 'e', 'l', 'l', 'o' };

    // length は配列リテラルから推論される
    const b = [_]u8{ 'w', 'o', 'r', 'l', 'd' };

    std.log.info("{} {}", .{ a.len, b.len });

    // 変数の type を記述していても配列リテラルのtypeは指定しないと行けないっぽい
    var c: [3]i32 = [_]i32{ 1, 2, 3 };
    // こう書くとコンパイルエラー
    //var c: [3]i32 = { 1, 2, 3 };
    // これもコンパイルエラー
    //var c: [_]i32 = [_]i32{ 1, 2, 3 };

    c[1] = 10;

    // 要素へのアクセスは 0 オリジン
    std.log.info("{} {} {}", .{ c[0], c[1], c[2] });

    // 要素数が異なる代入はできない
    // var d: [4]i32 = c;
    // std.log.info("{}", .{d.len});
    // ./src/main.zig:53:21: error: expected type '[4]i32', found '[3]i32'
    //     var d: [4]i32 = c;
    //                     ^

今の時点でわからないのは以下の通りです。

終わりに

今回の内容は ziglearn に置いてあります。

普段 Go を書く機会が多く行末セミコロンがなくても大丈夫なのですが、Zig は必須なのでよくコンパイラに怒られています。早く慣れたいと思います。