Курс языка программирования 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

Комментарии

  1. Возвращаемый блок замыкается на $total: эта переменная живёт между вызовами, поэтому каждый вызов помнит сумму, оставшуюся от предыдущего.

  2. $total += $amount одновременно обновляет нарастающую сумму и возвращает её, — это и печатает каждый say: сперва 110, затем 135, затем 130.

  3. В другом варианте сумма хранится внутри самого блока, в переменной 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 по-прежнему снабжает каждый из них собственным начальным значением.

Навигация по курсу

Накопитель значений   |   Сумма квадратов чётных чисел