alias - D Programming Language

Menu

- Learn
- Documentation
  - Language Reference
  - Library Reference
  - Command-line Reference
  - Feature Overview
  - Articles
- Downloads
- Packages
- Community
  - Blog
  - Orgs using D
  - Twitter
  - Calendar
  - Discord (community-run)
  - Forums
  - IRC
  - Wiki
  - Issues
  - Contributing
  - Contributors
  - Foundation
  - Security Team
  - Donate
  - Sponsors
- Resources
  - Tour
  - Books
  - Tutorials
  - Tools
  - Editors
  - IDEs
  - run.dlang.io
  - Visual D
  - Acknowledgments
  - D Style
  - Glossary
  - Sitemap

Search
Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

# alias

##### `alias`

The `alias` keyword assigns aliases to existing names. `alias` is different from and unrelated to `alias this`.

###### Shortening a long name

As we have encountered in the previous chapter, some names may become too long to be convenient. Let's consider the following function from that chapter:

    Stack!(Point!double) randomPoints(size_t count) {
        auto points = new Stack!(Point!double);
        // ...
    }

Having to type `Stack!(Point!double)` explicitly in multiple places in the program has a number of drawbacks:

- Longer names can make the code harder to read.
- It is unnecessary to be reminded at every point that the type is the `Stack` data structure that contains objects of the `double` instantiations of the `Point` struct template.
- If the requirements of the program change and e.g. `double` needs to be changed to `real`, this change must be carried out in multiple places.

These drawbacks can be eliminated by giving a new name to `Stack!(Point!double)`:

    alias Points = Stack!(Point!double);

    // ...

    Points randomPoints(size_t count) {
        auto points = new Points;
        // ...
    }

It may make sense to go further and define two aliases, one taking advantage of the other:

    alias PrecisePoint = Point!double;
    alias Points = Stack!PrecisePoint;

The syntax of `alias` is the following:

        alias new_name = existing_name;

After that definition, the new name and the existing name become synonymous: They mean the same thing in the program.

You may encounter the older syntax of this feature in some programs:

        // Use of old syntax is discouraged:
        alias existing_name new_name;

`alias` is also useful when shortening names which otherwise need to be spelled out along with their module names. Let's assume that the name `Queen` appears in two separate modules: `chess` and `palace`. When both modules are imported, typing merely `Queen` would cause a compilation error:

    import chess;
    import palace;

    // ...

        Queen person;             // ← derleme HATASI

The compiler cannot decide which `Queen` has been meant:

    Error: chess.Queen at chess.d(1) conflicts with
    palace.Queen at palace.d(1)

A convenient way of resolving this conflict is to assign aliases to one or more of the names:

    import palace;

    alias PalaceQueen = palace.Queen;

    void main() {
        PalaceQueen person;
        // ...
        PalaceQueen anotherPerson;
    }

`alias` works with other names as well. The following code gives a new name to a variable:

        int variableWithALongName = 42;

        alias var = variableWithALongName;
        var = 43;

        assert(variableWithALongName == 43);

###### Design flexibility

For flexibility, even fundamental types like `int` can have aliases:

    alias CustomerNumber = int;
    alias CompanyName = string;
    // ...

    struct Customer {
        CustomerNumber number;
        CompanyName company;
        // ...
    }

If the users of this struct always type `CustomerNumber` and `CompanyName` instead of `int` and `string`, then the design can be changed in the future to some extent, without affecting user code.

This helps with the readability of code as well. Having the type of a variable as `CustomerNumber` conveys more information about the meaning of that variable than `int`.

Sometimes such type aliases are defined inside structs and classes and become parts of the interfaces of those types. The following class has a `weight` property:

    class Box {
    private:

        double weight_;

    public:

        double weight() const {
            return weight_;
        }
        // ...
    }

Because the member variable and the property of that class is defined as `double`, the users would have to use `double` as well:

        double totalWeight = 0;

        foreach (box; boxes) {
            totalWeight += box.weight;
        }

Let's compare it to another design where the type of `weight` is defined as an `alias`:

    class Box {
    private:

        Weight weight_;

    public:

        alias Weight = double;

        Weight weight() const {
            return weight_;
        }
        // ...
    }

Now the user code would normally use `Weight` as well:

        Box.Weight totalWeight = 0;

        foreach (box; boxes) {
            totalWeight += box.weight;
        }

With this design, changing the actual type of `Weight` in the future would not affect user code. (That is, if the new type supports the `+=` operator as well.)

###### Revealing hidden names of superclasses

When the same name appears both in the superclass and in the subclass, the matching names that are in the superclass are hidden. Even a single name in the subclass is sufficient to hide all of the names of the superclass that match that name:

    class Super {
        void foo(int x) {
            // ...
        }
    }

    class Sub : Super {
        void foo() {
            // ...
        }
    }

    void main() {
        auto object = new Sub;
        object.foo(42);            // ← derleme HATASI
    }

Since the argument is 42, an `int` value, one might expect that the `Super.foo` function that takes an `int` would be called for that use. However, even though their parameter lists are different, `Sub.foo` hides `Super.foo` and causes a compilation error. The compiler disregards `Super.foo` altogether and reports that `Sub.foo` cannot be called by an `int`:

    Error: function deneme.Sub.foo () is not callable
    using argument types (int)

Note that this is not the same as overriding a function of the superclass. For that, the function signatures would be the same and the function would be overridden by the `override` keyword. (The `override` keyword has been explained in the Inheritance chapter.)

Here, not overriding, but a language feature called name hiding is in effect. If there were not name hiding, functions that happen to have the same name `foo` that are added to or removed from these classes might silently change the function that would get called. Name hiding prevents such surprises. It is a feature of other OOP languages as well.

`alias` can reveal the hidden names when desired:

    class Super {
        void foo(int x) {
            // ...
        }
    }

    class Sub : Super {
        void foo() {
            // ...
        }

        alias foo = Super.foo;
    }

The `alias` above brings the `foo` names from the superclass into the subclass interface. As a result, the code now compiles and `Super.foo` gets called.

When it is more appropriate, it is possible to bring the names under a different name as well:

    class Super {
        void foo(int x) {
            // ...
        }
    }

    class Sub : Super {
        void foo() {
            // ...
        }

        alias generalFoo = Super.foo;
    }

    // ...

    void main() {
        auto object = new Sub;
        object.generalFoo(42);
    }

Name hiding affects member variables as well. `alias` can bring those names to the subclass interface as well:

    class Super {
        int city;
    }

    class Sub : Super {
        string city() const {
            return "Kayseri";
        }
    }

Regardless of one being a member variable and the other a member function, the name `city` of the subclass hides the name `city` of the superclass:

    void main() {
        auto object = new Sub;
        object.city = 42;        // ← derleme HATASI
    }

Similarly, the names of the member variables of the superclass can be brought to the subclass interface by `alias`, possibly under a different name:

    class Super {
        int city;
    }

    class Sub : Super {
        string city() const {
            return "Kayseri";
        }

        alias cityCode = Super.city;
    }

    void main() {
        auto object = new Sub;
        object.cityCode = 42;
    }

##### `with`

`with` is for removing repeated references to an object or symbol. It takes an expression or a symbol in parentheses and uses that expression or symbol when looking up other symbols that are used inside the scope of `with`:

    struct S {
        int i;
        int j;
    }

    void main() {
        auto s = S();

        with (s) {
            i = 1;    // means s.i
            j = 2;    // means s.j
        }
    }

It is possible to create a temporary object inside the parentheses. In that case, the temporary object becomes an lvalue, lifetime of which ends upon leaving the scope:

        with (S()) {
            i = 1;    // the i member of the temporary object
            j = 2;    // the j member of the temporary object
        }

As we will see later in the Pointers chapter, it is possible to construct the temporary object with the `new` keyword, in which case its lifetime can be extended beyond the scope.

`with` is especially useful with `case` sections for removing repeated references to e.g. an `enum` type:

    enum Color { red, orange }

    // ...

        final switch (c) with (Color) {

        case red:       // means Color.red
            // ...

        case orange:    // means Color.orange
            // ...
        }

##### Summary

- `alias` assigns aliases to existing names.
- `with` removes repeated references to the same object or symbol.

Copyright © 1999-2026 by the D Language Foundation | Page generated by Ddoc on Mon Aug 17 18:57:15 2026