Курс языка программирования Raku / Приложение 🆕 / Порядок выполнения и функции / Подпрограммы и функциональный стиль / Exercises / Накопитель значений
Решение: Накопитель значений
Вот один из возможных вариантов решения задачи.
Код
sub make-accumulator($start) {
my $total = $start;
return -> $amount { $total += $amount };
}
my $acc = make-accumulator(100);
say $acc(10);
say $acc(25);
say $acc(-5);🦋 Исходный код можно найти в файле accumulator.raku.
Вывод
110
135
130Комментарии
Возвращаемый блок замыкается на
$total: эта переменная живёт между вызовами, поэтому каждый вызов помнит сумму, оставшуюся от предыдущего.$total += $amountодновременно обновляет нарастающую сумму и возвращает её, — это и печатает каждыйsay: сперва110, затем135, затем130.В другом варианте сумма хранится внутри самого блока, в переменной
state. В отличие от обычнойmy, переменнаяstateинициализируется лишь однажды — при первом выполнении блока — и затем сохраняет своё значение между последующими вызовами:sub make-accumulator($start) { return -> $amount { state $total = $start; $total += $amount }; } my $acc = make-accumulator(100); say $acc(10); say $acc(25); say $acc(-5);
Каждый вызов
make-accumulatorпорождает новый блок со своейstate $total, поэтому разные накопители остаются независимыми, а замыкание на$startпо-прежнему снабжает каждый из них собственным начальным значением.