#
Style Guide
These coding conventions are not enforced by the compiler, but they are shipped in this documentation along with the compiler in order to provide a point of reference, should anyone wish to point to an authority on agreed upon Zig coding style.
#
Avoid Redundancy in Names
Avoid these words in type names:
- Value
- Data
- Context
- Manager
- utils, misc, or somebody's initials
Everything is a value, all types are data, everything is context, all logic manages state. Nothing is communicated by using a word that applies to all types.
Temptation to use "utilities", "miscellaneous", or somebody's initials is a failure to categorize, or more commonly, overcategorization. Such declarations can live at the root of a module that needs them with no namespace needed.
#
Avoid Redundant Names in Fully-Qualified Namespaces
Every declaration is assigned a fully qualified namespace by the compiler, creating a tree structure. Choose names based on the fully-qualified namespace, and avoid redundant name segments.
const std = @import("std");
pub const json = struct {
pub const JsonValue = union(enum) {
number: f64,
boolean: bool,
// ...
};
};
pub fn main() void {
std.debug.print("{s}\n", .{@typeName(json.JsonValue)});
}
Shell
$ zig build-exe redundant_fqn.zig
$ ./redundant_fqn
redundant_fqn.json.JsonValue
In this example, "json" is repeated in the fully-qualified namespace. The solution
is to delete Json from JsonValue. In this example we have
an empty struct named json but remember that files also act
as part of the fully-qualified namespace.
This example is an exception to the rule specified in
#
Whitespace
4 space indentation
Open braces on same line, unless you need to wrap.
If a list of things is longer than 2, put each item on its own line and exercise the ability to put an extra comma at the end.
Line length: aim for 100; use common sense.
#
Names
Roughly speaking: camelCaseFunctionName, TitleCaseTypeName,
snake_case_variable_name. More precisely:
If
xis atypethenxshould beTitleCase, unless it is astructwith 0 fields and is never meant to be instantiated, in which case it is considered to be a "namespace" and usessnake_case.If
xis callable, andx's return type istype, thenxshould beTitleCase.If
xis otherwise callable, thenxshould becamelCase.Otherwise,
xshould besnake_case.
Acronyms, initialisms, proper nouns, or any other word that has capitalization rules in written English are subject to naming conventions just like any other word. Even acronyms that are only 2 letters long are subject to these conventions.
File names fall into two categories: types and namespaces. If the file
(implicitly a struct) has top level fields, it should be named like any
other struct with fields using TitleCase. Otherwise,
it should use snake_case. Directory names should be
snake_case.
These are general rules of thumb; if it makes sense to do something different,
do what makes sense. For example, if there is an established convention such as
ENOENT, follow the established convention.
#
Examples
const namespace_name = @import("dir_name/file_name.zig");
const TypeName = @import("dir_name/TypeName.zig");
var global_var: i32 = undefined;
const const_name = 42;
const primitive_type_alias = f32;
const string_alias = []u8;
const StructName = struct {
field: i32,
};
const StructAlias = StructName;
fn functionName(param_name: TypeName) void {
var functionPointer = functionName;
functionPointer();
functionPointer = otherFunction;
functionPointer();
}
const functionAlias = functionName;
fn ListTemplateFunction(comptime ChildType: type, comptime fixed_size: usize) type {
return List(ChildType, fixed_size);
}
fn ShortList(comptime T: type, comptime n: usize) type {
return struct {
field_name: [n]T,
fn methodName() void {}
};
}
// The word XML loses its casing when used in Zig identifiers.
const xml_document =
\\<?xml version="1.0" encoding="UTF-8"?>
\\<document>
\\</document>
;
const XmlParser = struct {
field: i32,
};
// The initials BE (Big Endian) are just another word in Zig identifier names.
fn readU32Be() u32 {}
See the Zig Standard Library for more examples.
#
Doc Comment Guidance
- Omit any information that is redundant based on the name of the thing being documented.
- Duplicating information onto multiple similar functions isencouraged because it helps IDEs and other tools provide better helptext.
- Use the word assume to indicate invariants that cause unchecked Illegal Behavior when violated.
- Use the word assert to indicate invariants that cause safety-checked Illegal Behavior when violated.