Bài tập 1, học cách vận dụng Closure

Câu hỏi: Điền vào chỗ trống để hàm bên dưới trả về một closure, và mỗi lần gọi closure này thì biến đếm tăng lên 1.

<?php
function createCounter() {
    // điền code vào đây
}

$counter = createCounter();

echo $counter(); // 1
echo $counter(); // 2
echo $counter(); // 3

Quy tắc:

  • Không được dùng biến global
  • Không được dùng từ khoá static trong OOP
  • Biến đếm phải lưu trữ trong hàm

Câu hỏi mở rộng: điều gì xảy ra khi đáp án của bạn xài Arrow Function.

Bài tập 2, học cách vận dụng từ khoá Yield

PHP cung cấp từ khoá Yield, đây là nền tảng của Coroutine. Yield dùng để tạo lazy sequence, không tốn bộ nhớ cho Array và giữ lại execution state giữa các lần chạy.

Ví dụ:

<?php
//hold $start vào RAM rồi mới nhả
//nếu $start có 1_000_000 phần tử thì tốn bộ nhớ tương ứng.
function countdown($start) {
    $result = [];
    for ($i = 0; $i < $start; $i++) {
        $result[] = $i + 1;
    }
    return $result;
}

$gen = countdown(5);

foreach ($gen as $value) {
    echo $value, PHP_EOL; // in từ 1 -> 5 ra màn hình
}

đổi lại xài yield

<?php
//không tốn công RAM, chỉ ném ra giá trị $i là Generator, sau đó pause hàm này lại
//đây là nền tảng của Coroutine
function countdown($start) {
    for ($i = 0; $i < $start; $i++) {
        yield $i + 1;
    }
}

$gen = countdown(5);

foreach ($gen as $value) {
    echo $value, PHP_EOL; // vẫn in từ 1 -> 5 ra màn hình
}
 

Câu hỏi: Điền vào chỗ trống để hàm bên dưới in ra 10, 20, 30

<?php

function countdown($start) {
    for ($i = 0; $i < $start; $i++) {
        yield $i + 1;
    }
}

function multiplyBy($x, $y) {
    // điền code vào đây 
}

$gen = countdown(3);
$mul = multiplyBy($gen, 10);
foreach ($mul as $v) {
    echo $v, PHP_EOL; // in ra 10, 20, 30 tuần tự
}

Quy tắc: Hàm multiplyBy nhận generator $x, dùng yield để nhân mỗi giá trị của generator gốc lên hệ số $y.

Gợi ý: theo ví dụ trên thì hoàn toàn loop $x được.

By admin