D Quick Reference
This page condenses D's core syntax — variable declaration, arrays and associative arrays, functions and templates, control flow, and the most commonly reached-for Phobos modules — into a single lookup you can scan when you already understand D but need the exact syntax for a specific construct, rather than a full explanation of why it works.
Cricket analogy: Like a fielding chart taped to the dugout wall that a captain glances at between overs rather than a full coaching manual, this quick reference is for a fast lookup, not a first-time explanation.
Core Syntax: Variables, Types, and Arrays
Declare variables with an explicit type (int y = 10;), infer the type with auto (auto name = "Ada";), or lock a value permanently with immutable (immutable double PI = 3.14159;). Dynamic arrays are declared as T[] (int[] nums = [1, 2, 3];), slices are taken with arr[start .. end], elements are appended with ~=, and associative arrays map keys to values directly with the V[K] syntax (int[string] scores = ["Ada": 100];).
Cricket analogy: Like a scorecard with clearly labeled columns for runs, balls, and fours rather than free-form notes, D's typed variable declarations give each value a clearly labeled slot.
import std.stdio;
import std.algorithm : map, filter;
import std.conv : to;
void main()
{
// Variables & type inference
auto name = "Ada"; // string, inferred
int age = 30;
immutable double PI = 3.14159;
// Arrays & slices
int[] nums = [1, 2, 3, 4, 5];
auto firstThree = nums[0 .. 3];
// Associative array
int[string] scores = ["Ada": 100, "Grace": 95];
// UFCS + lazy range pipeline
auto evens = nums.filter!(n => n % 2 == 0).map!(n => n * n);
// foreach over a range
foreach (n; evens)
write(n, " ");
writeln();
// String conversion
string ageText = age.to!string;
writeln(name, " is ", ageText, " years old");
}Functions, Templates, and UFCS
A function is declared as returnType name(params) { ... }, with default argument values (int add(int a, int b = 1) { return a + b; }) and auto for an inferred return type. A template function adds a compile-time type parameter list, T max(T)(T a, T b) { return a > b ? a : b; }, instantiated automatically for whatever type is passed. Uniform Function Call Syntax lets you write x.f(y) for any free function f(x, y), which is what makes range pipelines like nums.filter!(n => n > 0).map!(n => n * 2) read left to right.
Cricket analogy: Like a standard field-placement template a captain reuses and tweaks slightly for each different bowler, a D template function is written once and instantiated for whichever type is passed in.
auto infers both variable types (auto x = 5;) and function return types (auto square(int n) { return n * n; }); the compiler determines the concrete type from the initializer or return expression, but the inferred type is still fixed and static — D remains statically typed even when you don't write the type explicitly.
Control Flow and Error Handling
Standard if/else, while, and for all use C-like syntax; foreach (item; range) is the idiomatic way to iterate over arrays and ranges, and foreach (i, item; range) also gives you the index. switch/case works as in C, but D adds final switch for enums, which forces you to handle every enum member explicitly or the compiler rejects the code — there is no implicit fallthrough to a default. Exceptions use try/catch/finally with throw new Exception("message"), and custom exception types subclass Exception or Error depending on whether the condition is recoverable.
Cricket analogy: Like an umpire's exhaustive checklist covering every possible dismissal type before a final decision, D's final switch on an enum forces you to handle every enum member or the compiler rejects the code.
Assigning one dynamic array to another (arr2 = arr1;) copies the slice (pointer + length), not the underlying data — both arr1 and arr2 point to the same memory, so mutating an element through arr2 (arr2[0] = 99;) is visible through arr1 too. Call arr1.dup to get an independent copy when you need one, and be aware that appending to a slice (~=) may or may not allocate a new backing array depending on remaining capacity, which can silently change whether two slices still alias each other.
Common std Library Modules Cheat Sheet
std.stdio covers console and file I/O (writeln, File); std.algorithm provides range-based transformations (map, filter, sort, reduce); std.range provides range building blocks (iota, chain, take, zip); std.string handles text operations (split, strip, toUpper, indexOf) while std.format covers format-string style output; std.conv provides the to!T() conversion function used everywhere for type conversion; and std.file covers filesystem operations (readText, exists, write, dirEntries).
Cricket analogy: Like a team's specialist coaches each owning one distinct skill — batting coach, bowling coach, fielding coach — Phobos splits responsibilities across modules: std.stdio for I/O, std.algorithm for transformations, std.conv for conversions.
- Declare variables with an explicit type, auto for inference, or immutable to lock a value permanently.
- Arrays are T[], slices use arr[start .. end], and associative arrays use V[K] syntax like int[string].
- Function templates (T max(T)(T a, T b) {...}) and UFCS (x.f(y) for f(x, y)) are the backbone of idiomatic, chainable D code.
- auto infers both variable types and function return types while keeping D fully statically typed.
- final switch on an enum forces exhaustive case handling, catching a missed enum member at compile time.
- Array assignment copies the slice reference, not the data — use .dup to get an independent copy.
- std.stdio, std.algorithm, std.range, std.string, std.conv, and std.file cover the vast majority of everyday D tasks.
Practice what you learned
1. What does assigning one D dynamic array to another (arr2 = arr1;) actually copy?
2. What syntax declares an associative array mapping string keys to int values?
3. What does final switch on an enum require?
4. What does UFCS (Uniform Function Call Syntax) allow you to write?
5. Which std library module provides the to!T() conversion function?
Was this page helpful?
You May Also Like
D vs C++
A practical comparison of D and C++ covering memory management, compile-time metaprogramming, syntax safety, and tooling to help you decide when D is the better fit for a systems project.
D Best Practices
Practical conventions for writing idiomatic, maintainable D: default immutability, range-based pipelines, deliberate GC management, and design-by-contract testing.
D Interview Questions
The concepts D interviewers actually probe: struct vs class semantics, the function attribute system, template constraints, and the actor-model concurrency of std.concurrency.
Building a CLI Tool in D
A hands-on walkthrough of building a command-line tool in D: parsing arguments with std.getopt, handling files and errors safely, and packaging a release binary with dub.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics