【发布时间】:2011-12-25 03:36:10
【问题描述】:
我一直在使用alias,但今天我偶然发现D 有typedef。有趣的是,据我所知,TDPL 甚至没有涵盖它(甚至没有在D Keywords 和勘误表中列出)。 site does cover it,不过不多说。我的代码可以使用其中任何一个进行编译,但是两者之间有什么区别,我应该什么时候使用 typedef 而不是 alias?
【问题讨论】:
标签: d
我一直在使用alias,但今天我偶然发现D 有typedef。有趣的是,据我所知,TDPL 甚至没有涵盖它(甚至没有在D Keywords 和勘误表中列出)。 site does cover it,不过不多说。我的代码可以使用其中任何一个进行编译,但是两者之间有什么区别,我应该什么时候使用 typedef 而不是 alias?
【问题讨论】:
标签: d
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 将模板TypeDef 添加到std.typecons,复制标准库中typedef 的功能。
【讨论】:
'typedef' 关键字是 D1 的残余,并且一直打算被弃用。从 D 2.057 开始,它已被完全弃用。使用 D2 时应始终使用别名。
【讨论】:
struct f{}; struct g{};;这是两个定义的类。这不是:struct f{}; typedef f g;。尽管f 或g 的具体使用行为相同,但在后者中这是非法的:void x(f); void x(g);。