評価2: 開発環境のセットアップと基本操作 - 評価基準
評価の目的
この評価では、学生がZig開発環境を正しくセットアップし、基本的なビルドツール、コンパイラオプション、ファイルI/Oなどの実践的なスキルを習得しているかを確認します。開発環境の適切な構築は、効率的な開発の基盤となります。
学習目標
- Zigツールチェーンのインストールと動作確認ができる
- 基本的なZigコマンド(run、build-exe、test)を使用できる
- コマンドライン引数を処理できる
- ファイルの読み書きとエラー処理を実装できる
- build.zigを作成し、プロジェクト構造を理解できる
- クロスコンパイルの概念と実践ができる
- 最適化オプションの違いを理解し、活用できる
評価項目
1. インストールと環境確認(15点)
| 項目 | 配点 | 評価基準 |
|---|---|---|
| **Zigのインストール** | 5点 | 5点:最新の安定版または推奨版がインストールされている 3点:古いバージョンだが動作する 0点:インストールされていない、または動作しない |
| **バージョン確認** | 3点 | 3点:`zig version`の出力が正しく提出されている 2点:出力はあるが情報が不完全 0点:提出なし |
| **コマンド理解** | 4点 | 4点:`zig help`の出力を確認し、主要コマンドの役割を理解している 2点:出力のみで理解が不十分 0点:確認していない |
| **ターゲット確認** | 3点 | 3点:`zig targets`の出力を確認し、クロスコンパイルの概念を理解 2点:出力のみ 0点:確認していない |
評価のポイント:
- Zig 0.11.0以上が推奨(2023年以降の機能サポート)
- 主要コマンドの理解:
run,build-exe,build,test,fmt,cc - ターゲットプラットフォームの多様性の認識
2. Hello Worldプログラム(20点)
| 項目 | 配点 | 評価基準 |
|---|---|---|
| **基本実装** | 8点 | 8点:正しく動作し、"Hello, Zig!"を出力 5点:動作するが出力が異なる 2点:コンパイルエラー 0点:未実装 |
| **実行方法の理解** | 8点 | 8点:3つの方法(run、build-exe、最適化ビルド)すべてで実行確認 6点:2つの方法で実行 3点:1つの方法のみ 0点:実行できない |
| **コード品質** | 4点 | 4点:適切なインポート、mainシグネチャ、フォーマット 2点:動作するが品質に問題 0点:品質が低い |
実装チェックポイント:
const std = @import("std");
pub fn main() void {
std.debug.print("Hello, Zig!\n", .{});
}
const std = @import("std");の正しい使用pub fn main()の適切な定義std.debug.printのフォーマット指定子理解
3. コマンドライン引数処理(25点)
| 項目 | 配点 | 評価基準 |
|---|---|---|
| **引数取得** | 7点 | 7点:`std.process.argsAlloc`を正しく使用 5点:動作するが不完全 2点:部分的に動作 0点:取得できない |
| **メモリ管理** | 6点 | 6点:allocatorの使用とdeferによる解放が適切 4点:動作するがメモリリーク 0点:メモリ管理なし |
| **条件分岐** | 6点 | 6点:引数なしの場合に使用方法を表示 4点:条件分岐はあるが不完全 0点:条件分岐なし |
| **出力フォーマット** | 6点 | 6点:要件通りの出力(プログラム名、引数数、番号付きリスト) 4点:一部のみ表示 2点:基本的な出力のみ 0点:出力なし |
評価ポイント:
argsAllocとargsFreeのペア使用args[0]がプログラム名であることの理解- 引数の反復処理(for文またはwhile文)
- フォーマット指定子の適切な使用
4. ファイル入出力(40点)
| 項目 | 配点 | 評価基準 |
|---|---|---|
| **ファイル書き込み** | 12点 | 12点:`writeFile`関数が正しく動作し、内容が正確に書き込まれる 9点:基本的には動作するが、エラー処理が不十分 5点:部分的に動作 0点:動作しない |
| **ファイル読み込み** | 12点 | 12点:`readFile`関数が正しく動作し、内容を返す 9点:基本的には動作するが、メモリ管理が不十分 5点:部分的に動作 0点:動作しない |
| **エラー処理** | 10点 | 10点:適切なエラー型の使用とtry/catchの実装 7点:基本的なエラー処理はあるが不完全 3点:エラー処理が不十分 0点:エラー処理なし |
| **リソース管理** | 6点 | 6点:ファイルのclose、メモリの解放が適切に実装されている 4点:一部のリソース管理が不適切 0点:リソースリーク |
実装チェックポイント:
writeFile関数:
pub fn writeFile(filename: []const u8, content: []const u8) !void {
const file = try std.fs.cwd().createFile(filename, .{});
defer file.close();
try file.writeAll(content);
}
readFile関数:
pub fn readFile(allocator: std.mem.Allocator, filename: []const u8) ![]u8 {
const file = try std.fs.cwd().openFile(filename, .{});
defer file.close();
const content = try file.readToEndAlloc(allocator, 1024 * 1024);
return content;
}
ボーナス課題の評価
Bonus 1: build.zigの作成(15点)
| 配点 | 評価基準 |
|---|---|
| 15点 | 完全なbuild.zigを実装し、ビルド・実行・テストがすべて動作する |
| 12点 | ビルドと実行は動作するが、テストが不完全 |
| 8点 | 基本的なビルドのみ動作 |
| 4点 | build.zigは作成したが動作しない |
| 0点 | 未実装または重大なエラー |
評価チェックポイント:
std.Buildの正しい使用- 実行ファイルの定義(
addExecutable) - モジュールの追加(
addModule) - runステップの実装
- testステップの実装
- 適切なプロジェクト構造
標準的なbuild.zig例:
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable(.{
.name = "myapp",
.root_source_file = .{ .path = "src/main.zig" },
.target = target,
.optimize = optimize,
});
b.installArtifact(exe);
const run_cmd = b.addRunArtifact(exe);
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
const tests = b.addTest(.{
.root_source_file = .{ .path = "src/utils.zig" },
.target = target,
.optimize = optimize,
});
const test_step = b.step("test", "Run tests");
test_step.dependOn(&b.addRunArtifact(tests).step);
}
Bonus 2: クロスコンパイル(15点)
| 配点 | 評価基準 |
|---|---|
| 15点 | 3つ以上のターゲットで正しくビルドでき、バイナリの違いを分析している |
| 12点 | 3つのターゲットでビルドできるが、分析が浅い |
| 8点 | 2つのターゲットでビルド成功 |
| 4点 | 1つのターゲットのみ |
| 0点 | クロスコンパイルできない |
評価ポイント:
-targetオプションの正しい使用- 異なるアーキテクチャ(x86_64、aarch64)
- 異なるOS(linux、windows、macos)
- バイナリサイズの比較と分析
- 実行可能性の確認(可能な範囲で)
例:
zig build-exe -target x86_64-linux calculator.zig -femit-bin=calculator-linux-x64
zig build-exe -target x86_64-windows calculator.zig -femit-bin=calculator-windows.exe
zig build-exe -target aarch64-linux calculator.zig -femit-bin=calculator-linux-arm64
Bonus 3: ZLS統合とエディタ設定(10点)
| 配点 | 評価基準 |
|---|---|
| 10点 | ZLSが正しく動作し、スクリーンショットで機能を実証している |
| 7点 | ZLSはインストールされているが、一部の機能のみ動作 |
| 4点 | インストールのみで動作確認なし |
| 0点 | 未設定 |
評価基準詳細:
- ZLSのバージョン確認(0.10.0以上推奨)
- エディタ設定ファイルの提出
- 以下の機能のスクリーンショット:
Bonus 4: パフォーマンス比較(20点)
| 配点 | 評価基準 |
|---|---|
| 20点 | 4つの最適化レベルすべてで測定し、詳細な分析レポートを作成 |
| 15点 | 4つのレベルで測定したが、分析が不十分 |
| 10点 | 3つのレベルで測定 |
| 5点 | 2つ以下、または測定方法に問題 |
| 0点 | 未実施または不正確 |
評価ポイント:
- 4つの最適化レベル:Debug、ReleaseSafe、ReleaseFast、ReleaseSmall
- 実行時間の正確な測定
- バイナリサイズの記録
- 以下を含む分析:
レポート必須項目:
## ベンチマーク結果
| 最適化レベル | 実行時間 | バイナリサイズ | 特徴 |
|--------------|----------|----------------|------|
| Debug | XXX ms | XXX KB | ... |
| ReleaseSafe | XXX ms | XXX KB | ... |
| ReleaseFast | XXX ms | XXX KB | ... |
| ReleaseSmall | XXX ms | XXX KB | ... |
## 分析
...
評価チェックリスト
マンダトリー要件(必須)
- [ ] Zigが正しくインストールされている(zig version出力あり)
- [ ] Part 2のhello.zigがすべての方法で実行できる
- [ ] Part 3のargs.zigが引数を正しく処理する
- [ ] Part 3でメモリリークがない(valgrindまたは目視確認)
- [ ] Part 4のwriteFile関数が動作する
- [ ] Part 4のreadFile関数が動作する
- [ ] Part 4でファイルが正しくクローズされている
- [ ] すべてのコードがコンパイルエラーなく動作する
- [ ] エラー処理が適切に実装されている
- [ ] 提出物のディレクトリ構造が要件を満たす
コード品質
- [ ] 適切なインデントとフォーマット
- [ ] 意味のある変数名
- [ ] 必要な場所にコメント
- [ ] エラーメッセージがわかりやすい
- [ ] deferによるリソース管理
- [ ] try/catchの適切な使用
ボーナス要件
- [ ] Bonus 1: build.zigでビルド・実行・テストが動作
- [ ] Bonus 1: プロジェクト構造が適切
- [ ] Bonus 2: 3つのターゲットでビルド成功
- [ ] Bonus 2: バイナリサイズを比較している
- [ ] Bonus 3: ZLSが動作している(スクリーンショット)
- [ ] Bonus 3: エディタ設定ファイルが適切
- [ ] Bonus 4: 4つの最適化レベルで測定
- [ ] Bonus 4: 詳細な分析レポート
合格基準
| レベル | 点数 | 説明 |
|---|---|---|
| **優秀** | 90-100点 | すべての基本要件を満たし、複数のボーナス課題を完成。開発環境を完全に理解し、効率的に使用できる。 |
| **良好** | 80-89点 | 基本要件を十分に満たし、一部のボーナス課題に取り組んでいる。開発の基礎が確立している。 |
| **合格** | 70-79点 | 基本要件を概ね満たしている。いくつかの改善点はあるが、次のステップに進める水準。 |
| **要再提出** | 0-69点 | 重要な要件が不足、または実装に重大な問題。環境構築の復習と再提出が必要。 |
最低合格条件
- マンダトリー課題で70点以上
- Part 4のファイルI/Oが正しく動作
- メモリリークやリソースリークがない
- 段階的なアプローチ
学習の手引き
効果的な学習方法
- エラーメッセージの理解
- ドキュメントの活用
- 実験的な学習
よくある間違いと対策
間違い1: メモリリーク
// ❌ 間違い
pub fn main() !void {
const allocator = std.heap.page_allocator;
const args = try std.process.argsAlloc(allocator);
// argsFreeを忘れている
}
// ✅ 正しい
pub fn main() !void {
const allocator = std.heap.page_allocator;
const args = try std.process.argsAlloc(allocator);
defer std.process.argsFree(allocator, args);
}
間違い2: ファイルクローズの忘れ
// ❌ 間違い
pub fn writeFile(filename: []const u8, content: []const u8) !void {
const file = try std.fs.cwd().createFile(filename, .{});
try file.writeAll(content);
// closeを忘れている
}
// ✅ 正しい
pub fn writeFile(filename: []const u8, content: []const u8) !void {
const file = try std.fs.cwd().createFile(filename, .{});
defer file.close();
try file.writeAll(content);
}
間違い3: エラー処理の省略
// ❌ 間違い
const file = std.fs.cwd().openFile("test.txt", .{});
// tryがない
// ✅ 正しい
const file = try std.fs.cwd().openFile("test.txt", .{});
defer file.close();
間違い4: 最大ファイルサイズの未指定
// ❌ 問題あり
const content = try file.readToEndAlloc(allocator, std.math.maxInt(usize));
// メモリを無制限に確保しようとする
// ✅ 正しい
const content = try file.readToEndAlloc(allocator, 1024 * 1024); // 1MB制限
defer allocator.free(content);
デバッグのヒント
- コンパイルエラーのデバッグ
- 実行時エラーのデバッグ
std.debug.printで変数の値を確認
- エラーの種類(error型)を確認
- スタックトレースを読む- メモリリークのデバッグ
std.heap.GeneralPurposeAllocatorを使用してリーク検出
- valgrindツールの活用(Linux)- パフォーマンスのデバッグ
std.time.nanoTimestamp()で時間計測
- Debugビルドで詳細情報取得
- ReleaseFastビルドで最終的なパフォーマンス確認環境別セットアップガイド
Linux
# Zigのインストール
wget https://ziglang.org/download/0.11.0/zig-linux-x86_64-0.11.0.tar.xz
tar xf zig-linux-x86_64-0.11.0.tar.xz
sudo mv zig-linux-x86_64-0.11.0 /usr/local/zig
export PATH=$PATH:/usr/local/zig
# ZLSのインストール
wget https://github.com/zigtools/zls/releases/download/0.11.0/zls-linux-x86_64-0.11.0.tar.xz
tar xf zls-linux-x86_64-0.11.0.tar.xz
sudo mv zls /usr/local/bin/
macOS
# Homebrewを使用
brew install zig zls
# または手動インストール
# https://ziglang.org/download/ からダウンロード
Windows
# Scoopを使用
scoop install zig zls
# または手動インストール
# https://ziglang.org/download/ からダウンロードしてPATHに追加
推奨エディタ設定
VS Code
拡張機能のインストール:- Zig Language (ziglang.vscode-zig)
settings.json:
{
"zig.path": "/usr/local/bin/zig",
"zig.zls.path": "/usr/local/bin/zls",
"zig.initialSetupDone": true,
"editor.formatOnSave": true,
"zig.formattingProvider": "zls"
}
Neovim
init.lua:require'lspconfig'.zls.setup{
cmd = {'/usr/local/bin/zls'},
filetypes = {'zig'},
root_dir = require'lspconfig'.util.root_pattern('.git', 'build.zig'),
}
Emacs
(use-package zig-mode
:ensure t
:config
(add-hook 'zig-mode-hook #'lsp))
時間配分の目安
| パート | 推奨時間 | 内容 |
|---|---|---|
| Part 1 | 30分-1時間 | インストール、動作確認 |
| Part 2 | 1-2時間 | Hello World実装とテスト |
| Part 3 | 2-3時間 | コマンドライン引数処理 |
| Part 4 | 3-4時間 | ファイルI/O実装 |
| Bonus 1 | 2-3時間 | build.zig作成 |
| Bonus 2 | 1-2時間 | クロスコンパイル |
| Bonus 3 | 1-2時間 | ZLS設定 |
| Bonus 4 | 2-3時間 | ベンチマーク |
合計: マンダトリーで6.5-10時間、ボーナス込みで12.5-20時間
評価後のフィードバック例
優秀な提出物の場合
素晴らしい環境構築とコード実装です。特にファイルI/Oの実装は
非常に丁寧で、エラー処理とリソース管理が適切に行われています。
build.zigの実装も標準的な構造に従っており、プロジェクト管理の
理解が優れています。
クロスコンパイルのバイナリサイズ比較とパフォーマンスベンチマークの
分析は非常に詳細で、最適化の影響を深く理解していることが分かります。
次のステップ: カスタムアロケータの実装や、より複雑なビルドシステムの
構築に挑戦することをお勧めします。
改善が必要な場合
基本的な実装はできていますが、以下の点で改善が必要です:
1. ファイルI/Oでdeferを使用していないため、エラー時にファイルが
クローズされない可能性があります。
2. コマンドライン引数のメモリ解放が行われていません。
3. エラーメッセージがユーザーフレンドリーでありません。
改善のヒント:
- すべてのリソース確保の直後にdeferを追加
- エラー型を適切に処理(try/catch)
- std.debug.printでわかりやすいメッセージを表示
参考: 公式ドキュメントのFile Systemセクションを復習してください。
参考資料
- Zig公式ドキュメント: https://ziglang.org/documentation/master/
- Zig Standard Library - fs: https://ziglang.org/documentation/master/std/#std.fs
- Zig Standard Library - process: https://ziglang.org/documentation/master/std/#std.process
- Zig Build System: https://ziglang.org/documentation/master/#Build-System
- ZLS GitHub: https://github.com/zigtools/zls
- Zig Learn - Chapter 2: https://ziglearn.org/chapter-2/