Курс по Raku / Функционално, паралелно, реактивно и уеб програмиране / Функционално програмиране / Генератори

Мързелив gather

Блокът gather е мързелив: той не се изпълнява целият наведнъж. Той произвежда стойности само когато те бъдат изтеглени, а това означава, че gather може да опише безкрайна редица и пак да е полезен — просто спирате да взимате стойности, когато ви стигнат.

Уловката е, че трябва да държите резултата мързелив. Съхраняването му в обикновен масив @array би се опитало да събере всяка стойност наведнъж, а за безкрайна редица това никога не свършва. Вместо това дръжте последователността в скалар (където тя остава мързелив Seq) и теглете отрязък от нея:

my $naturals = gather {
    my $n = 1;
    loop {
        take $n++;
    }
}

say $naturals[^5]; # (1 2 3 4 5)

loop никога не свършва, но се произвеждат само пет стойности, защото само толкова поискахме с [^5]. Можете да теглите и от началото с .head:

say (gather { my $n = 1; loop { take $n++ } }).head(3); # (1 2 3)

Именно мързеливостта позволява на gather безопасно да моделира безкрайни потоци: нищо не се изчислява, докато не потрябва, и вземате точно толкова, колкото искате.

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

Тест — gather и take   |   Съберете кубовете


💪 Или преминете направо към упражненията в този раздел.