我很难理解以下代码的范围:
(define (create-counter (x 1))
(let ([count 0])
(lambda()
(let ([temp count])
(set! count (+ x count)) temp))))
如果我使用:
(let ((c (create-counter ))) (+ (c) (c) (c) (c)))
代码工作但是如果我尝试使用:
(+ (create-counter)(create-counter)(create-counter)(create-counter))
这不行,给我一个0.有人可以帮助我彻底理解这个吗?如果可能的话,请比较其他语言,比如C / C ++,我会更容易抓住这个。感谢
答案 0 :(得分:2)
当您调用“create-counter”时,它会创建一个计数器,然后返回一个引用该特定计数器的过程。当您四次调用“创建计数器”时,您将创建四个独立的计数器;每个程序都指自己的计数器。当您调用“create-counter”一次然后调用生成的过程四次时,它只创建一个计数器,并将其递增四次。
将它与C进行比较有点困难,因为C和C ++在闭包方面相当薄弱;返回在另一个函数中定义的函数并不容易。
最接近的模拟可能是C ++中的“计数器”对象;将“create-counter”视为包含单个整数的对象的构造函数,并将结果过程视为“增量”方法,该方法增加该对象中包含的计数器。在第二个示例中,您将创建四个不同的对象,在第一个示例中,您将创建一个对象并将其“增量”方法调用四次。
答案 1 :(得分:2)
(define (create-counter (x 1))
(let ([count 0])
(lambda()
(let ([temp count])
(set! count (+ x count)) temp))))
转换为:
auto create_counter(int x=1){
int count=0;
return [x,count]()mutable{
int r=count;
count+=x;
return r;
};
}
一个简单的C ++ 14函数返回一个闭包对象。
执行此操作时:
(let ((c (create-counter ))) (+ (c) (c) (c) (c)))
是:
auto c = create_counter();
auto r = c()+c()+c()+c();
return r;
创建一个计数器,然后运行4次,返回0 1 2 3并添加到6。
在这种情况下:
(+ ((create-counter))((create-counter))((create-counter))((create-counter)))
是:
auto r = create_counter()()+create_counter()()+create_counter()()+create_counter()();
return r;
创建4个计数器,每个计数器运行一次。第一次运行计数器时,你得到0.所以这会增加到0。
闭包对象具有状态。每次调用它时都会返回一个更大的数字。
现在你可能不熟悉C ++ 11/14 lamnda。
auto create_counter(int x=1){
int count=0;
return [x,count]()mutable{
int r=count;
count+=x;
return r;
};
}
时
struct counter {
int x,count;
int operator()(){
int r=count;
count+=x;
return r;
};
};
counter create_counter(int x=1){
return {x,0};
}
带有一些语法糖。
我修复了原始代码中似乎是语法错误的问题。我不是专家,所以也许我弄错了。
顺便说一句,一个简短的创建计数器看起来像:
auto create_counter(int x=1){
return [=,count=0]()mutable{
int r=count;
count+=x;
return r;
};
}