🥨

zig と go

2022/10/01に公開

これは何?

以前 go の好きなところと嫌いなところ という記事を書いた。

上記の記事は、zig のことを何も知らないで書いたんだけど、ここで上げた項目について zig がどうなっているのかを、全部じゃないけど書いてみるという趣旨の記事。

❓ コンパイルが速い

zig がどうなのか、全然知らない。

👍 ビルドが簡単

go と同じぐらいかんたんだと思う。

👍 int の最大値・最小値を得る簡単な方法がある

まあそもそも int という型はないんだけどどの整数型にも最大値と最小値を得る簡単な方法がある。

👍 条件演算子(三項演算子)の代わりになるものがある

? : 演算子そのものはないんだけど、if が値を返すのでそれでよい。

👍 言語を決めている人たちが書式を決めている

go と同様。すばらしい。

❓ Windows, Linux, macOS で同じソースで割とちゃんと動きがち

まだほとんど使ってないので、同じソースで動きがちかどうかはわからない。

👍 クロスコンパイルが簡単

クロスコンパイルは go と同じぐらい簡単だと思う。

chan や go routine のようなものはない。

ない。気づいている範囲では、似たようなものもなさそう。

メモリの種類は重要

go と違って、ローカル変数のアドレスを返してそれを使ったら普通に死ぬ。

アドレスはだいたい取れそう

zig の場合、気づいた範囲ではだいたいアドレスが取れる。
でも、前述の通りローカル変数のアドレスを返すと不幸になるので要注意。

多重代入がないのでそれに伴う混乱はない

zig には多重代入がない。
あると便利なのになとは思う。

👍 generics が強い

zig の generics は強い。そして (C++ と違って) 書きやすそう。

ユーザー定義型が組込型のように振る舞えない

go と同様、zig のユーザー定義型は組み込み型のようには振る舞えない。
たぶんこれは例外を入れなかったことからくる帰結なので仕方がないんじゃないかと思っている。

go と違って標準ライブラリに多倍長整数がないように見える。
C のライブラリがそのまま使えるのでそれを使えということかな。

👍 エラー処理は盤石

zig の選択した作戦では、エラー処理をサボるためにはサボることを明記しないといけない。サボるとコンパイルエラーなので必ず気づく。

例外じゃなくてもこんなに堅牢になれるんだと感心した。

go range のような感じのものはない

zig には今のところ、 go の range に当たるような気持ちのわからない文法要素はない。

👍 狭化変換とそうでない変換の区別は万全

狭化変換とそうでない変換の区別がちゃんとできている。
実行時には型を見て、コンパイル時には値を見て安全かどうかを判断している。素晴らしい。

slice のようなものに追加する処理は普通な感じ。

go の slice にあたるものは、zig では stdArrayList など、かな。
普通にメソッド(メンバ関数)のように見えるもので追加する。素晴らしいと言うか、ふつう。

なお、go と違ってメモリ確保失敗のエラーを返すことがある。

使ったことがないから自信ないけど。

map の要素のメンバへの代入もできる

go の map に当たるものは、zig では stdHashMap など、かな。

map の要素型のメンバを一個だけ書き換えたい、みたいなばあい、HashMap に生えている getPtr という関数を使えばいいっぽい。

使ったことがないから自信ないけど。

👍 ケツカンマ対応

zig も、関数の引数までケツカンマ OK。素晴らしい。
この当たりは go の影響なのかもしれない。

go module のようなものは無さそう

今のところ、そういう感じのものはないっぽい。
今後に期待。

👍 defer と errdefer

zig には defer の他に errdefer があり、go で困るパターンが解消される。

困るパターンっていうのは

  • なんか使えるものを作って返したい。
  • 作るには何段階かの処理が必要。
  • 途中で失敗したら、作り途中のものを全部破棄したい。
  • 最後まで完成したら、破棄せずに完成品を返したい。

っていうやつ。作り途中のものを破棄して return するために defer を書いてしまうと、完成品でも defer が走ってしまうので、ちょっとゴニョゴニョする必要がある。

zig には errdefer があるのでゴニョゴニョしなくてもスッキリ書ける。

❓ なにかとグローバルな状態を使ってしまうライブラリがあるかどうかはわからない

zig の標準ライブラリはまだあんまりチェックできてないんだけど、今のところそういう印象はない。

👍 四捨五入も三角関数も様々な浮動小数点に対応

三角関数も四捨五入も 32bit 浮動小数点数に対応している。
そればかりか、16bit 浮動小数点数にも対応している。

👍 複数の整数の最大値、整数の絶対値、などももちろんある

@maximum @minimum という組み込み関数があって、任意の型を受け取れる。
もしなかったとしても任意の型を受け入れるものをユーザーが定義するのはかんたん。

日付の書式化をする方法が標準には無い気がする

zig の標準ライブラリには日付の書式化をする方法が無い気がする。
C 言語で使う仕組みを使えということなのかなぁ。

👍 option 型があり、万全。

ある値が存在する場合に限って取り出せるような仕組みがある。
万全。

time.Duration のような型は無さそう

いまのところ、zig にそういう型は無さそう。

bit and + bit not

zig の場合、&~ という演算子を用意するのではなく、 a & ~1 をエラーにするという作戦にした。
エラーにしないで済む方法があるのになぁと思う。

👍 コメントがバイナリに影響を与えてしまうパターンは今の所無さそう

go のコメントで実現していたような機能は、zig では組み込み関数で実現している。

全体的には

エコシステムは、だいたい go が好み。
文法は、だいたい zig が好み。特にエラー処理と generics がとても良い。

ライブラリの整備具合は歴史の差もあって go が強いけど、go のライブラリには日付の書式とかわりと好きになれないポイントがあるし、generics が無い時代が長かったのでそれにまつわる不便を感じる。

zig のライブラリはまだほとんどつかってないけど、とても薄い感じがする。
今のところ、zig になければ C のライブラリ使えばいい、という態度だと思う。
zig として用意してあるものは、まあそうするよねという気持ちになる感じで好ましい。今後に期待。

Discussion