gpt4 book ai didi

scheme - 封装和封闭有什么区别?

转载 作者:太空宇宙 更新时间:2023-11-03 18:41:43 25 4
gpt4 key购买 nike

关于封装和闭包,我真的不明白。我相信封装是不能改变的,除非它被代码改变。但是当我被要求解释如何将闭包和封装应用于代码时,我无法真正理解。

例如 :

(define new-cercle #f)

(let ((n 0))
(set! new-cercle
(lambda (rayon)
(begin
(set! n (+ n 1))
(lambda (msg)
(cond ((eq? msg ’circonference)
(* 2 3.14 rayon))
((eq? msg ’surface)
(* 3.14 rayon rayon))
((eq? msg ’nb-cercles)
n)))))))
n是封装的吧?所以问题是:解释封装和闭包是如何应用于这段代码的。

我不明白的另一件事是为什么 let这里必须高于 lambda 吗?为什么当我把它放在 lambda 下方时,该功能不能正常工作并且没有累加器?
(define acc
(let ((n 1))
(lambda (x)
(set! n (* n x))
n)))

我希望有人能以简单的方式向我解释这一点,因为当我用谷歌搜索时,老实说,我对大多数主题都有的复杂示例一无所知。

最佳答案

封装模式的名称,涉及任何情况,在这种情况下,将一些相关项放在一个容器中,然后与该容器一起旅行,并通过该容器上的某种访问机制进行引用。这些项目可以是运行时值,或编译时标识符或其他任何东西。一个由多个字段组成的对象封装了字段:a cons细胞封装carcdr .一个类封装了槽。在一些对象系统中,方法也是。编译单元封装了它们的全局定义,例如函数和变量。

OOP 中“封装”的流行用法是指将类定义为一个单元,其中包含数据的定义以及对其进行操作的方法:代码和数据是一个“胶囊”。 (Common Lisp 对象系统不是这样的:方法没有封装在类中。)

闭包是另外一种东西,非常具体:它是一个程序代码体,连同它的词法环境,具体化为一个函数类型的对象。闭包的主体在被调用时对两组名称具有可见性:闭包的函数参数,以及创建闭包的词法范围中的周围名称。闭包是封装的一个例子:它将代码体与词法作用域一起封装。进入胶囊的唯一途径是通过函数:函数就像一个“方法”,被捕获的词法环境的元素就像一个对象中的“插槽”。

(通过结合代码和数据,Lisp 闭包比 Lisp 类对象更像封装的流行概念。)

关于那个有趣的词:在计算机科学中,“具体化”程序的某些方面是将一些不是一流对象的东西,并以某种方式将其变成一个。

几乎任何适用于理解程序的可识别概念都可能被具体化。 (聪明的人只需要提出一个关于如何做的明智的建议。)

例如,在给定执行点的整个 future 计算可以具体化,结果对象称为延续(更准确地说是无定界延续)。

当延续运算符捕获 future 计算时,该 future 成为假设:它实际上并没有发生(不执行)。取而代之的是,一个替代的 future 执行,其中将延续返回给运算符(operator)的调用者,或传递到调用者指定的函数中。现在掌握了这个延续的代码可以使用它来显式调用原始的、捕获的 future ,就好像它是一个函数一样。或者选择不这样做。换句话说,程序控制流(执行此块或不执行此块,或执行多次)已成为一个函数对象(调用此函数或不调用它,或多次调用它)。

对象是另一个具体化的例子:模块的具体化。老式程序分为具有全局函数和全局变量的模块。这种“模块”结构是我们可以在程序中识别并有用地应用于描述此类程序的概念。它很容易被具体化:我们可以想象,如果我们有一个“模块”的运行时对象,它具有所有相同的属性:即包含函数和数据,会怎样?而且,presto:基于对象的编程诞生了,具有相同模块的多个实例化等优点,因为变量不再是全局的。

关于 cerclerayon :

首先,new-cercle行为类似于对象的构造函数:它是一个可以从任何地方调用的全局函数。它维护已构造的对象数量。只有那个函数可以访问计数器,所以它被封装了。 (实际上不仅那个函数可以访问它,而且代表圆实例的闭包也可以访问它!)这是一个类模块封装的例子。它模拟模块,如语言 Modula-2 和类似语言中的模块,如带有 static 的 C 语言翻译单元。文件范围内的变量。

当我们拨打 new-cercle我们必须为 rayon 提供一个参数范围。生成并返回一个对象。该对象恰好是作为词法闭包生成的函数。这个闭包捕获了 rayon参数,从而封装了这个值:对象知道自己的半径。我们可以拨打new-cercle重复,并获得不同的圆圈实例,每个圆圈都有自己的 rayon .此 rayon外部不可见;它被封装在闭包内,并且只对该函数可见。

我们通过容器上的“消息”API 间接访问人造丝容器。我们可以使用消息符号 surface 调用该函数,它通过返回表面积来回答。当前可用的消息均未显示 rayon直接,但我们可以为此提供访问器消息,甚至是更改半径的消息。甚至还有访问共享变量n的消息,圆的计数,它的行为类似于对象系统(静态插槽)中的类变量:圆的任何实例都可以报告已经构造了多少个圆。 (请注意,此计数不会告诉我们当前存在多少个圆圈:当圆圈变成垃圾并被回收时,它不会递减:没有最终确定)。

无论如何,我们显然有一个容器,其内容只能通过接口(interface)访问。该容器将代码和数据绑定(bind)在一起,因此它不仅是封装,而且可以说是流行的 OOP 意义上的封装。

关于scheme - 封装和封闭有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34218876/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com