为了账号安全,请及时绑定邮箱和手机立即绑定

整个程序可以不变吗?

整个程序可以不变吗?

Qyouu 2021-04-08 14:11:01
我熟悉不变性并且可以设计不变性类,但是我大部分都是学术知识,缺乏实践经验请参考上面的链接图像(尚未嵌入)从下往上看学生需要一个新地址我们并没有真正改变学生,而是创建了一个包含新地址的新学生。mutator方法返回这个新对象问:假设mutator调用来自一个不可变的对象,该新对象将如何处理?不能将新学生保存在讲座中,因为讲座也是不可变的所以我们也需要一个新的讲座,其中包括新的学生但是在哪里保存新的讲座?当然,在新学期,它在哪里结束?至少可以通过使用组件外观模式来断开该链,该组件可以处理所有新对象的创建,而不必通过整个链转发呼叫问题:这在哪里停止?不必在某个地方至少有一个可变对象才能保存最顶层的实例吗?
查看完整描述

2 回答

?
慕娘9325324

TA贡献1783条经验 获得超4个赞

这就是函数编程的思想。一切都是不可变的,不允许任何函数调用产生副作用。像您的示例一样,突变复杂对象的唯一方法是重新创建父对象。

现在的问题是如何更改程序状态。因此,我们首先考虑堆栈。它包含所有局部变量的值以及被调用函数的所有参数的值。我们可以通过调用新函数来创建新值。我们可以通过从函数返回来丢弃值。因此,我们可以通过调用函数来改变程序状态。但是,并非总是可以从函数中返回以丢弃其局部变量,因为我们可能只希望丢弃某些局部变量,而需要保留其他局部变量的值以进行进一步的操作。在这种情况下,我们根本无法返回,但是我们需要调用另一个函数并将仅一些局部变量传递给该函数。现在,为了防止堆栈溢出,功能语言具有称为“尾部调用优化”的功能,能够从调用堆栈中删除不必要的条目。如果关联函数唯一要做的就是返回自身调用的函数的值,则不需要调用堆栈。在这种情况下,没有必要保留调用堆栈条目。通过删除不必要的调用堆栈条目,将丢弃原本未使用的局部变量的值。您可能想了解一下在这里。另外,尾递归与此有关。

同样,这是纯函数式编程语言(如Haskell)的想法。一切都是不可变的,这真是太好了,但是这些语言只有它们自己的问题,并且有自己的处理方式。例如,Monad(以及更高种类的类型)可以在这些语言中使用,但是在命令式/面向对象的编程语言中很少见。

我喜欢在程序存储器的叶子处具有不变的值。但是,构成这些不可变值的代码实际上构成了应用程序逻辑,但确实包含可变状态。对我来说,这结合了两个世界的优势。但是,这似乎是一个优先事项。


查看完整回答
反对 回复 2021-04-21
  • 2 回答
  • 0 关注
  • 139 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信