Подтвердить что ты не робот

Какая разница между `alias` и` typedef`?

Все это время я использовал alias, но сегодня я случайно обнаружил, что D имеет typedef. Достаточно интересно, что TDPL даже не покрывает его, насколько я могу судить (даже не указан в D Keywords или Ошибки). Сайт закрывает его, но он не говорит об этом много. Мой код тоже компилируется, но в чем разница между ними, и когда мне следует использовать typedef над alias?

4b9b3361

Ответ 1

alias создает новое имя для существующего. typedef работает только по типам и фактически создает новый тип:

alias int A;
typedef int B;

pragma(msg, is(A == int)); // true
pragma(msg, is(B == int)); // false

С помощью typedef вы также можете изменить инициализатор по умолчанию:

typedef int A = 42;

A a;
A[5] b;

void main()
{
    assert(a == 42);
    foreach(i; b) assert(i == 42);
}

alias является более общим. Он также работает с символами:

import std.stdio;
import std.conv : to;

alias to!(string) toString;

void main()
{
    int a;
    alias a b;
    a = 1;
    writeln(b); // 1

    string s = toString(2);
    writeln(s); // 2
}

alias также используется, когда вы хотите объединить наборы перегрузки:

import std.stdio;

class Base
{
    void foo() { writeln("base"); }
}

class Derived : Base
{
    alias super.foo foo; // merge overload sets

    void foo(int i) { writeln("derived"); }
}

void main()
{
    auto a = new Derived;
    a.foo(); // base
    a.foo(0); // derived
}

Без явного слияния вызов Base.foo с использованием экземпляра Derived недопустим, потому что Derived.foo скрывает его по умолчанию.

Это не только требуется для классов; если функции из двух разных импортированных модулей перегружают друг друга, они должны быть явно объединены с alias.

typedef устарел. Начиная с версии 2.057 DMD, для использования typedef требуется компиляция флага -d (для "устаревшего" ).

Этот запрос на перенос добавляет шаблон typedef в std.typecons, реплицируя функциональность typedef в стандартной библиотеке.

Ответ 2

Ключевое слово 'typedef' является остатком D1 и всегда предназначалось для устаревания. Начиная с D 2.057, он был полностью устарел. Вы должны всегда использовать псевдоним при работе с D2.