`alias`和`typedef`有什么区别?

时间:2011-12-25 03:36:11

标签: d

此时我一直在使用alias,但今天我偶然发现D有typedef。有趣的是,据我所知,TDPL甚至没有涵盖它(甚至没有在D Keywords和勘误表中列出)。 site does cover it,但它没有多说。我的代码可以编译,但是两者之间有什么区别,我应该何时使用typedef而不是alias

2 个答案:

答案 0 :(得分:19)

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已弃用。从DMD版本2.057开始,使用typedef需要编译-d(用于“已弃用”)标记。

This pull requestTypeDef添加了一个模板std.typecons,复制了标准库中typedef的功能。

答案 1 :(得分:7)

'typedef'关键字是D1的残余,并且总是打算弃用。自D 2.057起,它已被完全弃用。使用D2时,应始终使用别名。