提问人:Gaurav Singh 提问时间:12/2/2021 最后编辑:Gaurav Singh 更新时间:12/3/2021 访问量:92
我们可以说函数闭包是将状态保存给函数,每次我们给函数分配一个新状态时,它都会产生一个新函数吗?
Can we say function closure is saving a state to a function, and every time we assign a new state to the function it will result in a new function?
问:
在以下函数中,在 Scala 中调用 inc,它执行增量操作。
def inc(more:Int) = {
def helper(x:Int) = x+more
helper _
}
每当调用 inc 函数时,它都会返回另一个函数,该函数绑定传递给它的参数。例如,inc(1) 将返回另一个 Int => Int 类型的函数,其中变量 more 与 1 绑定。
inc(1) // This is of type Int => Int
那么我们可以说 more 是返回函数的状态变量,当我们调用 inc(1) 时,1 被分配给 more?
这里有一些进一步的阐述,
由于我来自OO编程范式,因此当我说状态时,我将其与类的实例相关联,该类在给定时间具有特定状态。让我们首先考虑一个 Java 中的类,调用 IncHelper,如下所示:
class IncHelper{
private int more;
public IncHelper(int more){
this.more = more;
}
public int inc(int x){
return x+this.more;
}
}
如果我创建上述类的不同实例,如下所示:
IncHelper inc1 = new IncHelper(1);
// This instance will always increase a value by 1
inc1.inc(10); // output will be 11
如果我创建上述类的不同实例,如下所示:
IncHelper inc2 = new IncHelper(2);
// This instance will always increase a value by 2
inc2.inc(10); // output will be 12
因此,在上述两种情况下,两个实例 inc1 和 inc2 包含两个不同的状态变量值。我给出的 Scala 函数式编程示例也是如此:
val inc1 = inc(1)
inc1(10) // Will return 11
如果我创建另一个值,如下所示:
val inc2 = inc(2)
inc2(10) // Will return 12
因此,在这两种情况下,即当我创建 IncHelper 的 2 个实例时,OO 编程会记住在构造它时传递的变量。同样,对于我们创建的两个函数文本也是如此,其中两个变量在创建函数文本 inc1 和 inc2 时传递了值。
答:
函数的闭包存储有关上下文的信息 - 此上下文是否由可变和/或不可变数据组成是另一回事。
我们只将函数称为有状态函数,因为它中有一些可观察到的可变状态(使函数在引用上不透明;打印等副作用算作可变状态)。因此,除非你有一些可能被变异的数据(拥有从未变异的 s 使它们有效不可变),否则根据通常的术语,你的函数没有状态。var
在您的情况下:
def inc(more:Int) = {
def helper(x:Int) = x+more
helper _
}
inc
不存储可变数据。 返回一个新值,但不改变 NOR 值。如果这样做:x+more
x
more
inc(1)
inc(1)
inc(1)
inc(1)
您每次都会得到相同的结果(具有相同行为的功能),并且没有副作用。因此,根据通常接受的术语,函数是无状态的,你不能说它有状态。事实上,里面有一些数据存储在里面......是无关紧要的,因为你曾经写过的每一段代码都是这样做的,所以一切都会被称为有状态的,有状态和无状态之间的区别几乎是无用的。Int => Int
inc
现在,如果您将函数定义为:
var state = 0
def inc(more:Int) = {
state = state + more
val y = state // binds current value of state
def helper(x:Int) = x + y
helper _
}
每次调用具有相同值的函数都会产生不同的值(此处为:具有不同行为的函数),因此会有一些状态可以讨论。( 函数将有一个状态 - 存储在 中,而返回的函数将是无状态的,因为它们只捕获不可变的值)。inc
Int => Int
int
var state
该状态问题将独立于闭包的概念 - 闭包只是“说”函数的定义使用创建时提供的一些数据,并且该函数仍然可以在您不再可以从它外部访问这些数据之后。
总而言之,如果创建该函数的环境中存在一些可变状态,并且该函数被该函数捕获(使用),我只会说(特定)“函数的闭包将状态保存到函数”。在其他情况下,我不会这么说,因为没有“状态”可以捕获。然而,由于这是非常不精确的陈述(函数是否捕获了可变状态的快照,而该快照本身是不可变的?还是函数捕获了对一些可变数据的引用,这些数据可以在其外部发生突变?我会完全避免它。
评论
[]
上一个:关于“帧作为本地状态的存储库”
评论