pure
自 TDPL 发布以来已经扩展了一点,因为pure
正如 TDPL 所描述的那样,事实证明它过于严格,无法在简单的数学函数等之外使用。您可以查看当前定义的在线文档,但基本上可以归结为:
pure
函数不能访问任何可以在程序过程中发生变化的模块级或静态变量(它们必须是const
值类型或immutable
从pure
函数中访问)。
pure
函数不能调用任何不是pure
.
pure
函数不能执行 I/O。
就是这样。没有其他限制。但是,如果要优化一个函数,即使在一个语句中多次使用它,它也只会被调用一次,则需要额外的限制。pure
即:
- 函数的参数必须可以
immutable
或隐式转换为immutable
.
从理论上讲,这可以扩展到要求函数的参数必须是immutable
或隐式转换为immutable
(以便const
在给定参数时可以优化带有参数的immutable
函数),但目前情况并非如此。
这样pure
的功能有时被称为“强” pure
,而那些无法优化的则被称为“弱” pure
。TDPL 描述了强pure
函数。添加了弱pure
功能以使其pure
更普遍可用。
虽然弱pure
函数可以改变它们的参数,但它们不能改变全局状态,所以当它们被强pure
函数(不能改变它们的参数)调用时,保证强pure
函数的返回值对于相同的函数总是相同的争论仍然成立。本质上,因为弱pure
函数不能改变全局状态,所以pure
它们是调用它们的强函数的私有状态的一部分。因此,它非常符合 Andrei 在第5.11.1.1 节pure
中描述的pure
TDPL中的情况,只是函数的私有状态已扩展为允许在不改变全局状态的情况下更改其私有状态的函数。
自 TDPL 以来添加的另一件重要的事情pure
是函数属性推断。pure
, nothrow
, 和@safe
被推断为模板函数(虽然不是普通函数)。因此,如果模板化函数可以是pure
,那么现在就是 pure
. 它的纯度取决于它的实例化。因此,可以pure
与模板函数一起使用,而以前通常不能,因为如果你做了它pure
,它将无法与不纯函数一起使用。但是如果你没有做到pure
,那么你就不能用一个pure
函数来使用它,所以这是一个主要的问题pure
. 幸运的是,属性推断现在解决了这个问题。只要模板化函数在实例化时遵循上面列出的规则,那么它就被认为是pure
.