Bunで一躍脚光を浴びたzigを試してみた。
正直文法がよくわかっておらんがこんな感じなのか?みたいなところ。
DockerならAlpineがかなり導入楽で良さそうです。apk add zig
だけでいけるっぽい。
第一印象としては、「かなりC寄りのGo」って感じ。
ドキュメント・ツールの未整備っぽさも含めて、Rustと同等かやや易くらいの大変さはあるかもね。でもCよりは多分普通に良いだろうとは思います。確かに。
というのも、Rustはツールが良くて、警告も結構良い印象があるのです。VSCodeの拡張ツール・言語サーバを入れるとそこそこ良くなりますが、う~ん、、って言いたくなる記法ミスとか上手く拾ってくれないので、ちょっと痛いですね。とはいえ、メモリ管理はそこそこ手動なのでちょい怖さがあります。そもそもこの言語、Ver1.0になるんだろうか笑
今のところCコンパイラとしての優秀さがzigは光っているようで、色々なところで見かけるので、それを試したいなあと思う次第。
そんな感じで、とりあえずクラスとリスト回すのを雰囲気で書いてみたが、とりあえずOKそうだった。構造体はどこかPythonっぽい。Enumにメソッド乗っけられるの良いね。
何より興味深いのはconst
がそのまま「型」になったり、構造体(enumやunionと合わせてコンテナーと言うらしい)で名前空間を表現したりするところかなあ。@
が「組み込み関数」ってのも独特です。この感じはちょっと見たことないって気がした。
const std = @import("std");
const Group = enum {
User,
Guest,
fn to_string(self: @This()) []const u8 {
switch (self) {
.User => return "User",
.Guest => return "Guest",
}
}
};
const User = struct {
allocator: std.mem.Allocator,
name: []const u8,
group: Group,
age: u32,
fn init(allocator: std.mem.Allocator, name: []const u8, group: Group, age: u32) !*User {
const u = try allocator.create(User);
u.* = .{
.allocator = allocator,
.name = name,
.group = group,
.age = age,
};
return u;
}
fn deinit(self: *@This()) void {
self.allocator.destroy(self);
}
};
pub fn main() !void {
// メモリ管理を行うアロケータを作成する
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa.allocator();
defer std.debug.assert(gpa.deinit() == std.heap.Check.ok);
// ユーザのリスト
var users = std.ArrayList(*User).init(allocator);
defer {
for (users.items) |user| {
user.deinit();
}
users.deinit();
}
// 追加
try users.append(try User.init(allocator, "Jhon", Group.User, 42));
try users.append(try User.init(allocator, "Doe", Group.Guest, 32));
if (users.items.len > 0) {
users.items[0].name = "Jorge";
}
// foreach
for (users.items) |user| {
std.debug.print("Hello, {s}! You are {d} years old. Group is {s}\n", .{ user.name, user.age, user.group.to_string() });
}
}