什么';“alias”和“typedef”之间的区别是什么?
一直以来,我都在使用什么';“alias”和“typedef”之间的区别是什么?,d,D,一直以来,我都在使用别名,但今天我偶然发现D有类型定义。有趣的是,据我所知,TDPL甚至没有涵盖它(甚至没有在D关键字中列出,也没有在勘误表中列出)。是的,但是它没有太多地谈论它。我的代码可以使用其中一个进行编译,但是这两者之间有什么区别,我应该在何时使用typedef而不是alias?关键字“typedef”是D1的残余,并且总是被弃用。截至D 2.057,它已被完全弃用。使用D2时应始终使用别名。alias为现有名称创建新名称typedef仅对类型有效,并实际创建一个新类型: alias i
别名
,但今天我偶然发现D有类型定义
。有趣的是,据我所知,TDPL甚至没有涵盖它(甚至没有在D关键字中列出,也没有在勘误表中列出)。是的,但是它没有太多地谈论它。我的代码可以使用其中一个进行编译,但是这两者之间有什么区别,我应该在何时使用typedef
而不是alias
?关键字“typedef”是D1的残余,并且总是被弃用。截至D 2.057,它已被完全弃用。使用D2时应始终使用别名。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
}
当您要合并重载集时,还将使用别名
:
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
(表示“已弃用”)标志
将模板
TypeDef
添加到std.typecons
中,以复制标准库中TypeDef
的功能。别名是一种通用的别名功能;您可以使用它来别名字段、函数、变量、类型等。我们认为这比使用typedef更好,因为typedef只适用于类型。此外,typedef实际上是一个非常糟糕的关键字选择。@Zor:奇怪。。。它看起来非常直观(“在现有类型的基础上定义”一个新的“类型”),实际上它在定义句柄和许多其他东西时非常有用…@Mehrdad:就是这样,它没有定义新类型。在C++中考虑:<代码> StuttF{};结构g{}代码>;这是两个定义的类。这不是:struct f{};类型定义f g代码>。虽然f
或g
的具体使用行为相同,但在后者中这是非法的:void x(f);空隙x(g)
.typedef仍有几个用例,将转换为库功能。