这个纯函数如何能够修改非私有状态? [英] How is this pure function able to modify non-private state?

查看:114
本文介绍了这个纯函数如何能够修改非私有状态?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

TDPL,第2页. 167:

TDPL, p. 167:

,只要函数中的可变状态完全是暂时的(即分配在堆栈上)和 private (即没有通过引用传递给那些可能会污染它),那么该功能可以被认为是纯函数.

as long as the mutable state in a function is entirely transitory (i.e., allocated on the stack) and private (i.e., not passed along by reference to functions that may taint it), then the function can be considered pure.

import std.stdio : writeln;

struct M{
  int[4] _data;

  pure ref int opIndex(size_t i){ return _data[i]; }
}

pure M foo(ref M m){

  m[0] = 1234;
  return m;
}

void main(){

  M m1 = M([7, 7, 7, 7]);

  writeln(m1);
  foo(m1);
  writeln(m1);
}

// output:
// M([7, 7, 7, 7])
// M([1234, 7, 7, 7])

可变状态是暂时的,因为它在堆栈上,对吗?但这不是私人的.那么如何允许foo()修改m1?

The mutable state is transitory because it's on the stack, correct? But it's not private. So how is foo() allowed to modify m1?

推荐答案

pure进行了一些扩展,因为TDPL描述的pure过于严格,以至于不仅简单数学函数之类的东西.您可以查看在线文档中的当前定义,但实际上可以归结为:

pure has been expanded a bit since the release of TDPL, since pure as TDPL describes turns out to be far too restrictive to be useful beyond simple math functions and the like. You can look at the online documentation for the current definition, but it essentially comes down to this:

  1. pure函数无法访问在程序执行过程中可能发生突变的任何模块级或静态变量(必须是const值类型或immutable才能从pure中访问功能).

  1. pure functions cannot access any module-level or static variables which can be mutated during the course of the program (they must be const value types or immutable to be accessed from a pure function).

pure函数不能调用不是pure的任何函数.

pure functions cannot call any functions which are not pure.

pure函数无法执行I/O.

pure functions cannot perform I/O.

就是这样.没有其他限制.但是,如果要优化pure函数,以使其仅被调用一次,即使它在一条语句中被多次使用,则还有 额外的限制.即:

That's it. There are no other restrictions. However, there are additional restrictions required if a pure function is going to be optimized such that it only gets called one time even if it's used multiple times within a statement. Namely:

  • 该函数的参数必须为immutable或隐式转换为immutable.
  • The function's parameters must be immutable or implicitly convertible to immutable.

理论上可以扩展为要求该函数的自变量必须为immutable或隐式转换为immutable(这样,可以在给定具有const参数的函数时对其进行优化immutable参数),但目前并非如此.

In theory that could be expanded to requiring that the function's arguments must be immutable or implicitly convertible to immutable (so that a function with const parameters could be optimized when it's given immutable arguments), but that's not currently the case.

此类pure函数有时被称为强" pure,而那些无法优化的函数将被称为弱" pure. TDPL强烈描述了pure功能.为了使pure更通用,添加了功能较弱的pure功能.

Such pure functions are sometimes referred to as "strongly" pure, whereas those which cannot be optimized would be referred to as "weakly" pure. TDPL describes strongly pure functions. Weakly pure functions were added in order to make pure more generally usable.

虽然pure个弱函数 可以更改其参数,但是它们不能更改全局状态,因此当它们被强pure个强函数(不能更改其参数),以保证对于相同的参数,强力pure函数的返回值将始终相同.本质上,因为弱pure函数不能改变全局状态,所以它们是从中调用它们的强pure函数的私有状态的一部分.因此,这与Andrei在5.11.1.1节中的描述非常吻合 pure就像TDPL中的pure一样,不同之处在于该函数的私有状态已扩展为允许以下功能:可以更改其私有状态而无需更改全局状态.

While weakly pure functions can alter their arguments, they cannot alter the global state, so when they're called by strongly pure functions (which can't alter their arguments), the guarantee that the strongly pure function's return value will always be the same for the same arguments still holds. Essentially, because the weakly pure functions cannot mutate global state, they're part of the private state of the strongly pure function that they're called from. So, it's very much in line with what Andrei describes in section 5.11.1.1 pure is as pure Does in TDPL, except that the private state of the function has been expanded to allow functions which can alter its private state without altering global state.

自TDPL以来,与pure有关的另一项主要注意事项是函数属性推断.对于模板函数,可以推断为purenothrow@safe(对于正常函数,则为 not ).因此,如果可以将模板化函数 设为pure,则现在它的就是 pure.其纯度取决于实例化的内容.因此,可以将pure与模板函数一起使用,而以前通常不能使用,因为如果将其设为pure,则不能与不纯函数一起使用.但是,如果您没有将其设置为pure,则无法将其与 pure 函数一起使用,因此对于pure .幸运的是,属性推断现在可以解决此问题.只要模板化的函数在实例化时遵循上面列出的规则,就会被视为pure.

Another major thing of note which has been added since TDPL with regards to pure is function attribute inference. pure, nothrow, and @safe are inferred for templated functions (though not for normal functions). So, if a templated function can be pure, now it is pure. Its purity depends on what it's instantiated with. So, it becomes possible to use pure with templated functions, whereas before, you usually couldn't, because if you made it pure, it wouldn't work with an impure function. But if you didn't make it pure, then you couldn't use it with a pure function, so it was a major problem for pure. Fortunately, attribute inference fixes that now though. As long as a templated function follows the rules listed above when it's instantiated, then it's considered pure.

这篇关于这个纯函数如何能够修改非私有状态?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆