2017-11-11 102 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'更直接地测试它,它告诉你函数具有的实际属性。 –