Мне трудно понять объем следующего кода:
(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 ++, мне было бы легче поймать это. Спасибо
(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};
}
с некоторым синтаксисом сахара.
Я исправил синтаксическую ошибку в исходном коде. Я не эксперт, так что, возможно, я ошибся.
Кроме того, счетчик создания briefer выглядит так:
auto create_counter(int x=1){
return [=,count=0]()mutable{
int r=count;
count+=x;
return r;
};
}
Когда вы вызываете «create-counter», он создает счетчик, а затем возвращает процедуру, которая ссылается на этот конкретный счетчик. Когда вы вызываете «create-counter» четыре раза, вы создаете четыре отдельных счетчика; каждая процедура относится к своему счетчику. Когда вы вызываете «create-counter» один раз, а затем получающуюся процедуру четыре раза, она создает только один счетчик и увеличивает его четыре раза.
Сложно сравнить это с C, поскольку C и C ++ довольно слабы в области замыканий; нелегко вернуть функцию, определенную внутри другой функции.
Ближайшим аналогом может быть «встречный» объект в C ++; думать о «create-counter» как о конструкторе для объекта, содержащего одно целое число, а результирующую процедуру — как о методе «increment», который увеличивает счетчик, содержащийся в этом объекте. Во втором примере вы создаете четыре отдельных объекта, а в первом примере вы создаете один объект и вызываете его метод «приращения» четыре раза.