اذهب إلى المحتوى

السؤال

نشر

كنت أتصفح بعذ أكواد PHP على GitHub ووجدت الكود التالي:

<?php

function get_between($min, $max) 
{
    for ($i = $min; $i <= $max; $i++) {
        yield $i;
    }
}

من المفترض أن يقوم الكود السابق بتوليد مصفوفة من الأرقام بين min و max، لكن لم أفهم معنى yield هنا وما الذي تفعله، وعندما حاولت تنفيذ الدالة السابقة من خلال الكود التالي:

echo get_between(1, 12);

ظهر هذا الخطأ:

Fatal error: Uncaught Error: Object of class Generator could not be converted to string

ما المشكلة هنا؟ وما فائدة yield؟

Recommended Posts

  • 1
نشر

ينبغي أولا فهم ما الذي تقوم به الدوال المولدة generators قبل التطرق لـ yield نفسها، فالأولى تقتضي استعمال الأخيرة. 

تعد المولدات في PHP تقدم طريقة أسرع وأسهل لإستخدام المكررات Iterators، فبدل السياق التالي لإضافة 100 الى كل عنصر من مصفوفة عددية: 

function myFunct($items) {
    $result = [];
    foreach ($items as $item) {
        $result[] = $item + 100;
    }
    return $result;
}

يتم كتابة صيغة المولد كـ: 

function myFunct($items) {
    foreach ($items as $item) {
        yield $item + 100;
    }
}

ففي الأولى:

  • يتم انشاء مصفوفة جديدة.
  • نقوم تباعا باستعمال تكرارة foreach بالإضافة الى المصفوفة الجديدة كل عنصر من عناصر المصفوفة القديمة مضافا اليه 100.
  • وفي الأخير نقوم بإعادة المصفوفة الجديدة كخرج. 

أما في الثانية:

  • فنحن نقوم مباشرة بإضافة الـ 100 الى كل عنصر من عناصر المصفوفة القديمة.

وكل هذا يكون دون الحاجة حتى الى اعادة خرج أو اعادة تعيين مصفوفة جديدة لإعادتها كخرج لاحقا.

و yield هنا هي أساس عمل هاته الدالة المولدة، فهي تعمل بشكل مشابه لـ return سوى أن هاته الأخيرة توقف تنفيذ الشيفرة. و yield تواصل تنفيذها الى القيمة التي ما بعدها. بمعنى: لو استقبلت الدالة المولدة المصفوفة [1,2] فهي لن تعيد 1 وتوقف تنفيذ الشيفرة عند اول تكرارة، بل ستقوم بإعادة تعيين 1 بالقيمة المسندة الى yield وتواصل العملية الى 2 وهكذا. 

 

بجانب فرق السرعة والضغط على الخادم الذي يكون في صالح المولدات لما يكون الأمر متعلق بالمكررات، يختلف العائد في كل من الأولى والثانية قليلا. فعند استدعاء الدالة المولِّدة للمرة الأولى تعيد الدالة كائنًا من الصنف Generator.ولو قمت بتفحص عائد الدالة المولدة سترى ذلك: 

function myFunct($items) {
    foreach ($items as $item) {
        yield $item + 100;
    }
}

print_r(myFunct([0 ,1 , 2]));

الخرج: 

Generator Object
(
)

في حين ان خرج الدالة العادية الأولى سيكون عاديا: 

[100 ,101 , 102]

هذا الكائن المعاد يطبق واجهة المكرر Iterator يمكن الوصول الى قيمها التي تعرف كخصائص كالتالي: 

function myFunc($items) {
    foreach ($items as $item) {
        yield $item + 100;
    }
}

foreach(myFunc([1,2,3]) as $i){
    echo $i.'/';
}

// => 101/102/103/

قد تحتاج الاستزادة بالتعرف على المولدات في PHP و PHP Object Iteration.

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...