mis*_*tor 57 oop closures functional-programming object
闭包是穷人的对象,反之亦然.
我已经看到这个声明在 许多 地方网站(上包括SO),但我不太明白是什么意思.有人可以解释它究竟意味着什么吗?
如果可能,请在答案中包含示例.
mis*_*tor 61
对象是穷人的封闭.
考虑Java.Java是一种面向对象的编程语言,对真正的词法闭包没有语言级支持.作为一个解决方案的Java程序员使用匿名内部类,它可以关闭词法范围中可用的变量(前提是它们final).从这个意义上讲,对象是穷人的封闭.
关闭是穷人的对象.
考虑一下Haskell.Haskell是一种函数式语言,对真实对象没有语言级支持.然而,他们可以使用闭包中所述进行建模,这由奥列格Kiselyov和拉尔夫Lammel优秀论文.从这个意义上说,封闭是穷人的对象.
如果你来自OO背景,你可能会发现对象更自然的思考,因此可能会认为它们是一个比封闭更基本的概念.如果你来自FP背景,你可能会发现闭包更加自然,因此可能会认为它们是一个比对象更基本的概念.
故事的道德是封闭和对象是彼此可表达的想法,没有一个比另一个更基本.这就是正在审议的声明.
在哲学中,这被称为模型依赖的现实主义.
Ben*_*ter 57
关键是闭包和对象实现了相同的目标:在单个逻辑单元中封装数据和/或功能.
例如,您可以创建一个代表狗的Python类:
class Dog(object):
def __init__(self):
self.breed = "Beagle"
self.height = 12
self.weight = 15
self.age = 1
def feed(self, amount):
self.weight += amount / 5.0
def grow(self):
self.weight += 2
self.height += .25
def bark(self):
print "Bark!"
Run Code Online (Sandbox Code Playgroud)
然后我将类实例化为一个对象
>>> Shaggy = Dog()
Run Code Online (Sandbox Code Playgroud)
Shaggy对象内置了数据和功能.当我打电话时Shaggy.feed(5),他获得了一英镑.该磅存储在作为对象属性存储的变量中,这或多或少意味着它在对象内部范围内.
如果我正在编写一些Javascript,我会做类似的事情:
var Shaggy = function() {
var breed = "Beagle";
var height = 12;
var weight = 15;
var age = 1;
return {
feed : function(){
weight += amount / 5.0;
},
grow : function(){
weight += 2;
height += .25;
},
bark : function(){
window.alert("Bark!");
},
stats : function(){
window.alert(breed "," height "," weight "," age);
}
}
}();
Run Code Online (Sandbox Code Playgroud)
这里,我在一个函数中创建了一个范围,然后调用了该函数,而不是在一个对象中创建一个范围.该函数返回由某些函数组成的JavaScript对象.因为这些函数访问在本地作用域中分配的数据,所以不回收内存,允许您通过闭包提供的接口继续使用它们.
P D*_*ddy 14
最简单的对象只是在该状态下运行的状态和函数的集合.闭包也是状态的集合和在该状态下运行的函数.
假设我调用一个需要回调的函数.在这个回调中,我需要在函数调用之前对某些已知的状态进行操作.我可以创建一个体现此状态的对象("fields")并包含一个作为回调执行的成员函数("method").或者,我可以采取快速简便的("穷人")路线并创建一个封闭.
作为对象:
class CallbackState{
object state;
public CallbackState(object state){this.state = state;}
public void Callback(){
// do something with state
}
}
void Foo(){
object state = GenerateState();
CallbackState callback = new CallbackState(state);
PerformOperation(callback.Callback);
}
Run Code Online (Sandbox Code Playgroud)
这是伪C#,但在概念上与其他OO语言类似.正如您所看到的,回调类涉及到管理状态的大量样板文件.使用闭包会更简单:
void Foo(){
object state = GenerateState();
PerformOperation(()=>{/*do something with state*/});
}
Run Code Online (Sandbox Code Playgroud)
这是一个lambda(同样,在C#语法中,但概念在支持闭包的其他语言中类似),它为我们提供了类的所有功能,而无需编写,使用和维护单独的类.
你还会听到一个必然结果:"对象是一个穷人的封闭".如果我不能或不会利用闭包,那么我被迫使用对象来完成他们的工作,就像我的第一个例子.虽然对象提供了更多的功能,但是由于已经说明的原因,闭包通常是封闭工作的更好选择.
因此,没有对象的穷人通常可以通过闭包完成工作,而没有闭包的穷人可以使用对象完成工作.富人同时拥有并为每项工作使用正确的人.
编辑:问题的标题不包括"反之亦然"所以我会尽量不去假设提问者的意图.
两个共同阵营是功能性和命令式语言.两者都是可以通过不同方式以不同方式完成类似任务的工具.
关闭是穷人的对象.
对象是穷人的封闭.
单独地,每个陈述通常意味着作者有某种偏见,通常以一种语言或一种语言与另一种语言或语言的不适为基础.如果不是偏见,它们可能受到一个环境或另一个环境的约束.我读到的作者说,这种事情通常是狂热者,纯粹主义者或语言宗教类型.如果可能的话,我会避免语言宗教类型.
关闭是穷人的对象.对象是穷人的封闭.
这位作者是一位"实用主义者",也非常聪明.这意味着作者欣赏这两种观点并认识到它们在概念上是相同的.这是我的同伴.
小智 6
只是这么多糖,因为封闭物隐藏了裙子下面的匿名物品.
"对象是一个穷人的封闭"不仅仅是一些理论等价的陈述 - 它是一种常见的Java习语.使用匿名类来包装捕获当前状态的函数是很常见的.以下是它的使用方法:
public void foo() {
final String message = "Hey ma, I'm closed over!";
SwingUtilities.invokeLater(new Runnable() {
public void run() {
System.out.println(message);
}
});
}
Run Code Online (Sandbox Code Playgroud)
这甚至看起来很像使用另一种语言的闭包的等效代码.例如,使用Objective-C块(因为Objective-C与Java相似):
void foo() {
NSString *message = @"Hey ma, I'm closed over!";
[[NSOperationQueue currentQueue] addOperationWithBlock:^{
printf("%s\n", [message UTF8String]);
}];
}
Run Code Online (Sandbox Code Playgroud)
唯一真正的区别是功能包装在new Runnable()Java版本的匿名类实例中.
| 归档时间: |
|
| 查看次数: |
12320 次 |
| 最近记录: |