📝
【Zig】Zigを試しながらのHow toメモ
Home ⚡ Zig Programming Language
何か新しい言語をインプットしながら、何か作りたいと思い、最近よく目にするZigが良さそうだったので、作りながら色々試してメモした内容になります。
試した環境
macOS Monterey バージョン12.1 Apple M1
環境構築
Macの場合Homebrewで導入可能みたいなので、そちらでインストールしてみたいと思います。
$ brew install zig
現時点でのインストールVersionは 0.9.1
でした。
$ zig version
0.9.1
Hello world
何はともあれ、まずは Hello world
やってみます。
まずは初期化して、そのまま実行してみます。
$ zig init-exe
$ zig build run
info: All your codebase are belong to us.
init-exe
で以下が作成されます。
.
├── build.zig
└── src
└── main.zig
build run
でビルドと実行を行ってくれます。ビルドされた実行ファイルは zig-out/bin/xxxx
に作成されてました。
次に Hello world
を表示するためにsrc/main.zig
を以下に修正します。
zig build run
で Hello, world!
が表示されればOKです。
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
try stdout.print("Hello, {s}!\n", .{"world"});
}
import
別ファイルに定義した関数をimportして呼び出す場合、
funcs.zig
const std = @import("std");
pub fn debug() void {
std.log.debug("funcs#debug call", .{});
}
↑ 呼び出したい関数に pub
を付けます。
main.zig
const funcs = @import("funcs.zig");
const debug = funcs.debug;
pub fn main() void {
debug();
}
あとは、呼び出す側で @import
してやればOKです。
Allocator
Allocatorの種類
- c_allocator
- libcをリンクする場合に最適 (malloc_usable_sizeを使用する)
- raw_c_allocator
-
malloc
/free
を直接呼び出す (malloc_usable_sizeを使用しない)
-
- page_allocator
- メモリ割り当てと解放のたびに直接 syscall を呼び出す (Thread-safe and lock-free.)
- HeapAllocator
- windowsだけでしか使えない? 内部でHANDLEを使用
- ArenaAllocator
- 既存のアロケータをラップし、まとめて解放してくれる
- FixedBufferAllocator
- 固定長のバッファで事足りる場合に使用
- LogToWriterAllocator
- 他のアロケータを使う際に、指定したWriterにログを出力してくれる
- LoggingAllocator
- 他のアロケータを使う際に、
std.log
にログを出力してくれる
- 他のアロケータを使う際に、
基本的な使い方
const std = @import("std");
const expect = std.testing.expect;
test "allocation" {
const allocator = std.heap.page_allocator;
const memory = try allocator.alloc(u8, 100);
defer allocator.free(memory);
try expect(memory.len == 100);
try expect(@TypeOf(memory) == []u8);
}
LoggingAllocatorを使う場合
const std = @import("std");
const loggingAllocator = std.heap.loggingAllocator;
const allocator = loggingAllocator(std.heap.page_allocator).allocator();
// debug: alloc - success - len: 4602, ptr_align: 1, len_align: 1
// debug: free - len: 16384
ファイルの扱い
- ファイルオープン/クローズ
const std = @import("std");
pub fn main() !void {
const file_name = "xxxx";
const file = try std.fs.cwd().openFile(fileName, .{});
defer file.close();
}
- ファイルサイズの取得
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
const file_name = "xxxx";
const file = try std.fs.cwd().openFile(fileName, .{});
defer file.close();
const file_size = try file.getEndPos();
try stdout.print("file size: {d}\n", .{file_size});
}
- ファイルのRead
const std = @import("std");
pub fn main() !void {
const stdout = std.io.getStdOut().writer();
const file_name = "xxxx";
const file = try std.fs.cwd().openFile(fileName, .{});
defer file.close();
const file_size = try file.getEndPos();
try stdout.print("file size: {d}\n", .{file_size});
var reader = std.io.bufferedReader(file.reader());
var instream = reader.reader();
const allocator = std.heap. page_allocator;
const contents = try instream.readAllAlloc(allocator, file_size);
defer allocator.free(contents);
try stdout.print("read file value: {c}\n", .{contents});
}
複数の値をまとめてreturnしたい場合
pub fn getPosition() struct { start: i32, end: i32 } {
const start = 1000;
const end = 2000;
return .{
.start = start,
.end = end
};
}
structで束ねる様な形でreturnする
バッドノウハウ
brew install時に以下エラーに遭遇
Error: python@3.10: the bottle needs the Apple Command Line Tools to be installed.
You can install them, if desired, with:
xcode-select --install
You can try to install from source with:
brew install --build-from-source python@3.10
Please note building from source is unsupported. You will encounter build
failures with some formulae. If you experience any issues please create pull
requests instead of asking for help on Homebrew's GitHub, Twitter or any other
official channels.
Python3が必要なのでメッセージ通り、xcode-select --install
でコマンドラインツールをインストールして無事インストールできました。
$ python3 --version
Python 3.9.13
「もっとこうした方が〜」 などありましたら、アドバイス頂けると助かります!
また、メモが溜まったら記事にしたいと思います。
Discussion