D - 纯粹的类和结构

时间:2017-11-11 17:21:03

标签: d

出于好奇心,我输入了以下代码:

pure struct Foo{ }
pure class Bar{ }

显然,这与DMD和LDC都有关。我不知道它做了什么(如果它),因为从这样的结构/类调用不纯的函数是可以的。那么,将pure附加到类或结构会发生什么变化?

2 个答案:

答案 0 :(得分:8)

一般来说,D倾向于在不适用时忽略属性,如果没有别的话,因为通用代码更容易以这种方式编写(有时,它避免了必须编写一堆静态ifs)避免将属性应用于他们不会产生任何影响的代码) - 一个例子是你可以在模块级别上将static放在几乎任何声明上,但它实际上并没有做任何事情对于他们中的大多数人来说,编译器并没有抱怨它。

但是,无论出于何种原因,使用它们标记结构或类时应用属性的方式有点不一致。例如,如果您使用@safe标记了结构或类,那么该结构或类中的每个函数都将为@safe,除非它标有@trusted@system }。相反,如果使用pure标记类或结构,则它绝对没有任何意义 - 就像使用static一样。它被忽略了。

我最好猜测为什么像@safe这样的东西应用于结构或类中的所有函数,而purenothrow之类的属性被忽略的是{{通过在该函数上显式使用不同的属性,可以在结构或类中的特定函数上撤消1}},@safe@trusted,而对于大多数属性,无法反转它们。

不幸的是,当一个类或结构要么不适用时,或者当它们只应用于类或结构中的声明而不是类或结构本身时,你可以用属性标记一个类或结构的事实确实倾向于使人混淆(例如,有些人认为@system对于班级来说意味着特殊的东西,当它意味着班级中的声明是immutable class C {..}时;它与做immutable没有什么不同)。因此,最终,您必须熟悉每个属性实际应用于类或结构时实际知道的内容,当它们真正应用于类或结构内部的声明时,以及它们被简单地忽略时

就个人而言,我从不将属性应用于类或结构,除非它们专门用于应用于结构或类而不应用于其中的函数(例如,类上的class C { immutable { ... } }意味着与将它放在该类中的函数上),实际应用于结构或类的属性数量非常少。 final在某些情况下(仅在模块级别),staticabstract对类以及访问修饰符(finalpublic等执行。)做。根据TDPL,private也应该是特殊的类,但是同步类从未真正实现过(只是同步函数)。所以,我可能错过了一个,但在我的头脑中,这是可以实际应用于结构或类的完整属性列表,并且所有其他属性被忽略或应用于其中的声明结构或类,但不是结构或类本身。

答案 1 :(得分:2)

它什么都没改变。当D编译器放置在他们没有意义的位置时,D编译器会忽略许多关键字。

快速测试证明这一点:

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

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