2011-12-25 11 views
13

今回私はaliasを使用していましたが、今日はDがtypedefであることを偶然発見しました。面白いことに、TDPLは私が知る限りではそれをカバーしていません(D Keywordsも正誤表にも記載されていません)。 site does cover itですが、それについてはあまり話しません。私のコードはいずれかでコンパイルされますが、その2つの違いは何ですか?また、よりもtypedefを使用する必要がありますか?`alias`と` typedef`の違いは何ですか?

答えて

19

aliasは、既存のものの新しい名前を作成します。 typedefのみのタイプで動作し、実際に新しいタイプの作成:typedef

alias int A; 
typedef int B; 

pragma(msg, is(A == int)); // true 
pragma(msg, is(B == int)); // false 

を、あなたはまた、デフォルトの初期化子を変更することができます。

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デフォルトでそれを隠します。

これはクラスに必須ではありません。 2つの異なるインポートされたモジュールの関数が互いにオーバーロードされる場合は、明示的にaliasとマージする必要があります。

typedefは推奨されていません。 DMDバージョン2.057では、typedefを使用するには、-d( "廃止予定")フラグをコンパイルする必要があります。

This pull requestは、標準ライブラリのtypedefの機能を複製std.typeconsにテンプレートTypeDefを追加します。

7

'typedef'キーワードは、D1の残りの部分であり、常に非推奨となっています。 D 2.057以降、完全に廃止されました。 D2を使用する場合は、常にエイリアスを使用する必要があります。

+0

なぜ廃止されましたか? – Mehrdad

+0

エイリアスは一般化エイリアシング機能です。フィールド、関数、変数、型などのエイリアスに使用できます。これは、型に対してのみ機能するtypedefを持つよりも優れた設計であると判断されました。さらに、typedefは実際にはそれが何のためのキーワードの本当に貧しい選択です。 –

+0

@Zor:奇妙な...それはかなり直感的で(既存のものに基づいて新しいタイプを定義しているように)、実際にハンドルや他の多くのものを定義するのに非常に便利でした... – Mehrdad

関連する問題