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

Arl*_*len 13 d

这一直是我一直在使用alias,但今天我偶然发现D有typedef.有趣的是,据我所知,TDPL甚至没有涵盖它(甚至D Keywords没有在勘误表中列出).该网站确实涵盖了它,但它没有谈论它.我的代码编译有两种,但两者有何区别,什么时候应该使用typedefalias

jA_*_*cOp 19

alias为现有名称创建新名称.typedef仅适用于类型,实际上创建一个新类型:

alias int A;
typedef int B;

pragma(msg, is(A == int)); // true
pragma(msg, is(B == int)); // false
Run Code Online (Sandbox Code Playgroud)

使用typedef,您还可以更改默认初始值设定项:

typedef int A = 42;

A a;
A[5] b;

void main()
{
    assert(a == 42);
    foreach(i; b) assert(i == 42);
}
Run Code Online (Sandbox Code Playgroud)

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
}
Run Code Online (Sandbox Code Playgroud)

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
}
Run Code Online (Sandbox Code Playgroud)

如果没有显式合并,则不允许Base.foo使用实例进行调用Derived,因为Derived.foo默认情况下会隐藏它.

这不仅是课程所必需的; 如果来自两个不同导入模块的函数相互重载,则必须明确合并它们alias.

typedef已弃用.从DMD版本2.057开始,using typedef需要-d(for"deprecated")标志进行编译.

此拉取请求添加了一个模板,TypeDef用于std.typecons复制typedef标准库中的功能.


小智 7

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