此时我一直在使用alias
,但今天我偶然发现D有typedef
。有趣的是,据我所知,TDPL甚至没有涵盖它(甚至没有在D Keywords
和勘误表中列出)。 site does cover it,但它没有多说。我的代码可以编译,但是两者之间有什么区别,我应该何时使用typedef
而不是alias
?
答案 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 request向TypeDef
添加了一个模板std.typecons
,复制了标准库中typedef
的功能。
答案 1 :(得分:7)
'typedef'关键字是D1的残余,并且总是打算弃用。自D 2.057起,它已被完全弃用。使用D2时,应始终使用别名。