One way to define compound or custom types in D is to define them through a struct:

struct Person {
    int age;
    int height;
    float ageXHeight;

structs are always constructed on the stack (unless created with new) and are copied by value in assignments or as parameters to function calls.

auto p = Person(30, 180, 3.1415);
auto t = p; // copy

When a new object of a struct type is created, its members can be initialized in the order they are defined in the struct. A custom constructor can be defined through a this(...) member function. If needed to avoid name conflicts, the current instance can be explicitly accessed with this:

struct Person {
    this(int age, int height) {
        this.age = age;
        this.height = height;
        this.ageXHeight = cast(float)age * height;

Person p(30, 180); // initialization
p = Person(30, 180);  // assignment to new instance

A struct might contain any number of member functions. These are by default public and accessible from the outside. They could also be private and thus only be callable by other member functions of the same struct, or other code in the same module.

struct Person {
    void doStuff() {
    private void privateStuff() {

p.doStuff(); // call method doStuff
p.privateStuff(); // forbidden

Const member functions

If a member function is declared with const, it won't be allowed to modify any of its members. This is enforced by the compiler. Making a member function const makes it callable on any const or immutable object, but also guarantees to callers that the member function will never change the state of the object.

Static member functions

If a member function is declared as static, it will be callable without an instantiated object (e.g. Person.myStatic()) but won't be allowed to access any non-static members. A static member function can be used to give access to all instances of a struct, rather than the current instance, or when the member function must be usable by callers that don't have an instance available. For example, Singletons (where only one instance is allowed) use static.


Note that a struct can't inherit from another struct. Hierachies of types can only be built using classes, which we will see in a future section. However, with alias this or mixins one can easily achieve polymorphic inheritance.



Given the struct Vector3, implement the following functions and make the example application run successfully:

  • length() - returns the vector's length
  • dot(Vector3) - returns the dot product of two vectors
  • toString() - returns a string representation of this vector. The function std.string.format returns a string using printf-like syntax: format("MyInt = %d", myInt). Strings will be explained in detailed in a later section.

rdmd playground.d