2017-11-11 3 views
3

はアイドル好奇心から、私は以下のコードで入力した:D純粋なクラスや構造体

pure struct Foo{ } 
pure class Bar{ } 

これは、明らかに、DMDとLDCの両方でコンパイルされます。そのような構造体/クラスからの不純な関数を呼び出すことはOKであるので、それが何であるか分かりません。ですから、pureをクラスや構造体に変更するとどうなりますか?

答えて

8

、Dは、彼らが適用されないときの属性を無視する傾向があり、何もない場合は、汎用的なコードがで(そのように書くことが容易であるため、何も効果がないコードに属性を適用するのを避けるために静的なifをたくさん書く必要はありません) - 例えば、モジュールレベルでほとんどすべての宣言にstaticを置くことができますが、ほとんどの場合、何もしません。コンパイラはそれについて不平を言っていません。

しかし、何らかの理由で、構造体またはクラスにマークを付けるときに属性が適用される方法は、少し矛盾しています。たとえば、@safeの構造体またはクラスをマークした場合、その構造体またはクラスのすべての関数は、@trustedまたは@systemとマークされていない限り、@safeになります。対照的に、クラスまたは構造体をpureとマークすると、それは絶対に何もしません。staticのようになります。それは単に無視されます。

pureまたはnothrowなどの属性は無視されるのに対し、@safeのようなものは、構造体やクラス内のすべての機能に適用される理由の私の最高の推測では@safe@trusted、および@systemは、内の特定の機能に元に戻すことができるということです構造体またはクラスをその関数で明示的に別の属性を使用することによって実現できます。一方、ほとんどの属性では、それらを逆にする方法はありません。

残念ながら、クラスまたは構造体に属性が適用されていない場合、またはクラスまたは構造体自体の宣言にのみ適用される場合は、クラスまたは構造体をマークすることはできません(例えば、immutable class C {..}がクラスにとって特別な意味を持つと思う人もいるでしょう。つまり、クラス内の宣言はimmutableです;それはclass C { immutable { ... } }と異ならないでしょう)。したがって、最終的には、各属性がクラスまたは構造体に実際に適用するとき、クラスまたは構造体内の宣言に実際に適用するとき、およびそれらを単純に無視するときに、それぞれの属性が実際に何をしているかに精通していなければなりません。

個人的には、クラスまたは構造体に属性を適用することは特にありません。構造体またはクラスに適用されるもので、内部の関数には適用されません(たとえば、クラス上のfinalは、そのクラス内で)実際に構造体やクラスに適用される属性の数はかなり少ないです。 staticは、いくつかのコンテキスト(モジュールレベルではない)、abstractおよびfinalはクラス用であり、アクセス修飾子(public,privateなど)はそうです。 TDPLでは、​​もクラスにとって特別なものになっていますが、同期クラスは実際には実装されていません(同期された関数のみ)。だから私は見逃しているかもしれませんが、私の頭の上から外すと、それは実際に構造体またはクラスに適用できる属性の完全なリストであり、他のすべては無視されるか、構造体またはクラス内の宣言に適用されます構造体またはクラス自体には適用されません。

2

変更はありません。 Dコンパイラは、多くのキーワードが意味を持たない場所に配置された場合、単に無視します。

簡単なテストは、これを証明するには:一般的に

pure struct S { 
    static void bar() {} 
} 

pure unittest { 
    static assert(!__traits(compiles, S.bar())); 
} 
+3

'std.traits.functionAttributes'を使って直接テストすることができます。これは、関数が持つ実際の属性を示します。 –

関連する問題