Modules, Packages and Visibility

15.1 Modules and Imports

myapp/
├── dub.json
└── source/
    ├── app.d                 module app;
    └── mylib/
        ├── package.d         module mylib;  (public imports for the package)
        ├── math.d            module mylib.math;
        └── utils/strings.d   module mylib.utils.strings;
module mylib.math;
public import mylib.utils.strings;     // re-export to importers
import std.stdio;                      // private import (default)

int add(int a, int b) { return a + b; }
private int helper() { return 0; }     // visible only in this module
package int forPackage() { return 1; } // visible within the mylib package
// package.d
module mylib;
public import mylib.math, mylib.utils.strings;
import mylib;                          // imports everything in package.d
import mylib.math : add;               // selective
import m = mylib.math;                 // renamed
static import std.math;                // must be fully qualified: std.math.sqrt
void f() { import std.algorithm : sort; }   // scoped (local) import: good practice

15.2 Visibility Attributes

Same module (not just the class!) Same package (and subpackages with package(pkgname)) Same module + subclasses Everyone (default) Exported from shared libraries/DLLs

15.3 Module Constructors and Destructors

Circular imports are allowed, but circular static constructors cause a runtime error (cycle detection).

static this() { /* per-thread module initialization */ }
static ~this() {}
shared static this() { /* once at program start */ }
shared static ~this() {}