2011-12-25 143 views
13

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

回答

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 
} 

没有明确的合并,使用Derived一个实例不允许调用Base.foo,因为Derived.foo隐藏它默认情况下。

这不仅仅是需要的类;如果来自两个不同导入模块的功能彼此过载,则必须将它们明确地与alias合并。

typedef已弃用。从DMD版本2.057起,使用typedef需要编译-d(用于“弃用”)标志。

This pull request增加了一个模板TypeDefstd.typecons在标准库中复制了typedef的功能。

7

'typedef'关键字是D1的补遗,并且始终打算废弃。从D 2.057开始,它已被完全弃用。使用D2时应始终使用别名。

+0

为什么不推荐使用? – Mehrdad 2011-12-25 04:00:42

+0

别名是一种广义混叠功能;您可以使用它来替换字段,函数,变量,类型等。有人认为,这是比只适用于类型的typedef更好的设计。而且,typedef实际上是关键字的一个非常糟糕的选择。 – 2011-12-25 04:11:28

+0

@Zor:奇怪......它看起来非常直观(基于现有的“定义”一个新的'类型'),它在定义HANDLE和其他许多事情方面非常有用... – Mehrdad 2011-12-25 08:10:28