Zig Standards
Zig Standards
Section titled “Zig Standards”1. Build System
Section titled “1. Build System”- Tool:
zig build.build.zigfor build configuration. - Version: Zig 0.11+ (use latest stable).
- Dependencies: Use
build.zig.zonfor package dependencies.
2. Code Style
Section titled “2. Code Style”- Formatter:
zig fmt. Run viamake fmtorzig fmt. - Linter: Compiler warnings. Use
@setRuntimeSafety(true)for safety checks. - Type Checker: Compiler is the type checker. Enable all warnings.
build.zig Example
Section titled “build.zig Example”const std = @import("std");
pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable(.{ .name = "project", .root_source_file = b.path("src/main.zig"), .target = target, .optimize = optimize, });
b.installArtifact(exe);}3. Naming Conventions
Section titled “3. Naming Conventions”- Files:
snake_case.zig - Types/Structs/Enums:
PascalCase - Functions/Variables:
camelCase - Constants:
UPPER_SNAKE_CASEorcamelCasewithconst - Private: No special prefix (use
pub/non-pubfor visibility)
4. Project Structure
Section titled “4. Project Structure”src/├── domain/│ ├── entities.zig│ └── value_objects.zig├── application/│ ├── use_cases.zig│ └── interfaces.zig└── infrastructure/ └── repositories.zig5. Language Features
Section titled “5. Language Features”- Memory Management: Manual memory management. Use allocators explicitly.
- Error Handling: Use error unions
!TorError!T. Usetry/catchfor error handling. - Optionals: Use
?Tfor nullable types. Useif (value) |v|for unwrapping. - Comptime: Leverage compile-time execution for metaprogramming.
Example
Section titled “Example”const std = @import("std");const Allocator = std.mem.Allocator;
pub const Email = struct { value: []const u8,
pub fn init(allocator: Allocator, value: []const u8) !Email { if (!std.mem.containsAtLeast(u8, value, 1, "@") or !std.mem.containsAtLeast(u8, value, 1, ".")) { return error.InvalidEmail; } return Email{ .value = value }; }
pub fn deinit(self: *const Email, allocator: Allocator) void { _ = self; _ = allocator; // Free if allocated }};
pub const Result = union(enum) { success: void, failure: Error,
pub const Error = error{ InvalidEmail, UserNotFound, };};6. Error Handling
Section titled “6. Error Handling”- Error Sets: Define error sets explicitly. Use
error{}for custom errors. - Error Unions: Use
!TorError!Tfor fallible operations. - Propagation: Use
tryfor error propagation. Usecatchfor error handling.
pub const DomainError = error{ InvalidEmail, UserNotFound, DatabaseError,};
pub fn createUser( allocator: Allocator, email_str: []const u8, name: []const u8,) !User { const email = Email.init(allocator, email_str) catch |err| { return DomainError.InvalidEmail; }; return User.init(allocator, email, name);}7. Testing
Section titled “7. Testing”- Framework: Built-in
testblocks. Usezig test. - Test Structure: Use
test "description"blocks. Test in same file or separate test files.
Test Structure
Section titled “Test Structure”const std = @import("std");const testing = std.testing;
test "should create user with valid email" { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; defer _ = gpa.deinit(); const allocator = gpa.allocator();
const email = try Email.init(allocator, "test@example.com"); defer email.deinit(allocator);
const user = try User.init(allocator, email, "Test User"); defer user.deinit(allocator);
try testing.expectEqualStrings("test@example.com", user.email.value);}8. Memory Management
Section titled “8. Memory Management”- Allocators: Always pass allocators explicitly. Use appropriate allocator for use case.
- Ownership: Document ownership semantics. Use
deferfor cleanup. - Arena Allocators: Use
ArenaAllocatorfor temporary allocations.
pub fn processUsers(allocator: Allocator) !void { var arena = std.heap.ArenaAllocator.init(allocator); defer arena.deinit(); const arena_allocator = arena.allocator();
// Use arena_allocator for temporary allocations // Automatically freed when arena is deinit}9. Dependencies
Section titled “9. Dependencies”Common Libraries
Section titled “Common Libraries”- HTTP:
http.zigorh11for HTTP parsing - JSON:
std.json(standard library) - Database:
zig-sqliteor database-specific bindings - Logging: Custom logging or
std.log
10. Documentation
Section titled “10. Documentation”- Doc Comments: Use
///for public items,//!for module-level docs. - Format: Use Markdown. Include examples.
/// Creates a new user with validated email address.////// Arguments:/// - `allocator`: Memory allocator for user allocation/// - `email_str`: Valid email address (must match RFC 5322)/// - `name`: User's full name (non-null, non-empty)////// Returns:/// New `User` entity instance.////// Errors:/// - `DomainError.InvalidEmail` if email format is invalid////// Example:/// ```zig/// const user = try createUser(allocator, "test@example.com", "John Doe");/// defer user.deinit(allocator);/// ```pub fn createUser( allocator: Allocator, email_str: []const u8, name: []const u8,) !User { // Implementation}11. Performance
Section titled “11. Performance”- Zero-Cost Abstractions: Zig has minimal runtime overhead. Use comptime for optimizations.
- SIMD: Use
@Vectorfor SIMD operations when appropriate. - Profiling: Use
perforvalgrindfor performance profiling.
12. Safety
Section titled “12. Safety”- Runtime Safety: Use
@setRuntimeSafety(true)for safety checks in debug builds. - Undefined Behavior: Avoid undefined behavior. Use
@panic()for unreachable code. - Bounds Checking: Enable bounds checking in debug builds.
13. Build Modes
Section titled “13. Build Modes”- Debug:
-O Debug- Full safety checks, no optimizations. - ReleaseSafe:
-O ReleaseSafe- Safety checks enabled, optimized. - ReleaseFast:
-O ReleaseFast- No safety checks, maximum optimization. - ReleaseSmall:
-O ReleaseSmall- Optimized for size.