2017-11-11 107 views
3

出於無聊的好奇,我輸入了下面的一段代碼:d - 純類和結構

pure struct Foo{ } 
pure class Bar{ } 

這顯然既DMD和最不發達國家的編譯。我不知道它是幹什麼的(如果是這樣),因爲從這樣的結構體/類中調用不純的函數是可以的。那麼,將pure附加到類或結構更改上會發生什麼?

回答

8

一般來說,d有忽略的屬性時,他們不適用的傾向,如果不出意外,因爲通用的代碼更容易編寫的方式(在時間,它避免了必須編寫一堆靜態ifs,以避免將屬性應用於代碼,而不會對其產生任何影響) - 一個示例是,您可以將static放在模塊級別的幾乎任何聲明上,但它不會實際上大多數人都沒有做任何事情,編譯器也不會抱怨。

但是,無論出於何種原因,當您使用它們標記結構或類時,屬性的應用方式有點不一致。例如,如果您使用@safe標記了一個結構或類,則該結構或類中的每個函數將爲@safe,除非它標有@trusted@system。相比之下,如果您用pure標記類或結構,它絕對沒有 - 就像static一樣。它簡單地被忽略。

我最好的猜測,爲什麼像@safe被應用到所有的結構或類中的功能,而像purenothrow屬性被忽略的是@safe@trusted,並@system可以在中的特定功能被撤消該結構或類通過在該函數上顯式使用不同的屬性,而對於大多數屬性而言,無法將它們反轉。

然而,不幸的是,當它們不適用或者只適用於類或結構中的聲明而不適用於類或結構本身時,可以使用屬性標記類或結構的事實往往會混淆人們(例如,有些人認爲immutable class C {..}對於班級意味着什麼特別的意思,當它意味着班級內的申報是immutable;這與class C { immutable { ... } }沒有什麼不同)。因此,最終,您必須熟悉每個屬性實際上知道什麼時候實際應用於類或結構,什麼時候它們實際上只適用於類或結構中的聲明,以及什麼時候它們被忽略。

個人而言,我從來不會將屬性應用於類或結構,除非它們專門用於結構或類,而不用於其中的函數(例如,類中的final意味着將某些東西與函數分開在該類中),而實際應用於結構或類的屬性數量非常小。 static在某些情況下(只是不在模塊級別),abstractfinal對類有效,並且訪問修飾符(public,private等)具有。根據TDPL,​​也應該是專門用於該類的,但同步類從未真正實現(只是同步函數)。所以,我可能錯過了一個,但是我的頭頂,這是可以實際應用於結構或類的完整屬性列表,其他所有屬性都被忽略或應用於結構或類中的聲明但不是結構或類本身。

2

它沒有改變。當D編譯器放置在他們無意義的位置時,D編譯器會簡單地忽略許多關鍵字。

簡單的測試來證明這一點:

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

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

你可以用'std.traits.functionAttributes'更直接地測試它,它告訴你函數具有的實際屬性。 –