পিএইচপি-তে: "রিটার্ন", "ফলন", "ফলন" থেকে এবং একই ফাংশনে ফলন এবং ফেরত উভয়ের মধ্যে পার্থক্য কী?


10

মধ্যে পার্থক্য returnএবং yieldস্পষ্ট করলো যতক্ষণ না আমি মূর্ত আউট এও দেখা গেল yield fromএবং সম্ভাবনা উভয় একত্রিত করতে returnএবং yieldখুব একই ফাংশনে!

আমার বোধগম্যতা কি returnসমস্ত কিছু পরে কার্যকর করা হয়নি , তাই না?

যাহোক:

function generate(): iterable {
    return [1, 2, 3];
}

foreach (generate() as $value) {
    echo $value;
}

প্রযোজনা: "123"

তবে নিম্নলিখিত:

function generate(): iterable {
    return [1, 2, 3];
    yield;
}

foreach (generate() as $value) {
    echo $value;
}

কিছুই উত্পাদন করে না! সুতরাং যে ফলন কার্যকর করা হয়?

এটি কি বাগ?


1
var_dump(generate()->GetReturn());
আব্রিকাডাভার

উত্তর:


10

Return

কলারকে কেবল একটি অনন্য মান ফিরিয়ে দেয়।

Yield

একটি ফিরিয়ে আনার জন্য বর্তমান ফাংশন / পদ্ধতির রূপান্তর করুন Generator, যা একটি অনন্য মানের থেকে বেশি উত্পাদন করবে: প্রতিবার yieldট্রিগার করা হয়, এটি কলকারীকে একবারে মূল্য দেয়, givesতিহ্যগতভাবে একটি foreachলুপ ব্যবহার করে ।

Yield + + Return

জেনারেটর, মান উত্পন্ন করা ছাড়াও, একটি অনন্য ফেরত মান সরবরাহ করতে পারে। এই মানটি জেনারেটরের চারপাশে লুপিংয়ের অংশ হবে না, এটি Generator::getReturn()পদ্ধতি ব্যবহার করে অবশ্যই অ্যাক্সেস করতে হবে ।

Return + + Yield

এটি একটি বাগ হিসাবে দেখা যেতে পারে, তবে এটি তা নয়।

তারা দুটি পর্যায়:

  1. কোড থেকে বাইটকোডে : এই ধাপের সময়, ফাংশনটিতেgenerate() মূল yieldশব্দটি রয়েছে বলে দেখা যায় , এটি একটি উত্পাদন হিসাবে চিহ্নিত হয়েছে Generator
  2. সম্পাদন : যেহেতু returnঘটেছিল তার আগে হওয়ার কারণে yield, জেনারেটরের কোনও মান উত্পাদন করার সুযোগ নেই। তবে [1, 2, 3]অ্যারেটি পুনরুদ্ধার করা যায় Generator::getReturn()

একটি সম্পূর্ণ টীকাযুক্ত উদাহরণ:

// Generate integers 1 and 2
function generateIntegers1And2(): Generator {
    yield 1;                                  // <--+   <--+   <--+
    yield 2;                                  //  <-+    <-+    <-+
}                                             //    |      |      |
                                              //    |      |      |
foreach (generateIntegers1And2() as $value) { //    |      |      |
    var_dump($value); // Shows 1, then 2          ->*      |      |
}                                                       // |      |
                                                        // |      |
function generateOuterYield(): Generator {              // |      |
    // Yields the generator *itself* returned by           |      |
    // generateIntegers1And2() not the actual values       |      |
    // generated by it.                                    |      |
    // This means we are producing here a generator        |      |
    // of generator of integers.                           |      |
    yield generateIntegers1And2();          // <-+         |      |
}                                             // |         |      |
                                              // |         |      |
foreach (generateOuterYield() as $value) {    // |         |      |
    var_dump($value);                       // ->*         |      |
    // The two levels of imbrication means we have         |      |
    // to loop once more to actually consume               |      |
    // generateIntegers1And2                               |      |
    foreach ($value as $val) {                          // |      |
        var_dump($val); // Shows 1, then 2               ->*      |
    }                                                          // |
}                                                              // |
                                                               // |
// A generator can just be returned as-is:                        |
function generateOuterReturn(): Generator {                    // |
    return generateIntegers1And2();                            // |
}                                                              // |
                                                               // |
// it doesn't change the way it is consumed                       |
foreach (generateOuterReturn() as $value) {                    // |
    var_dump($value); // Shows 1, then 2                          |
}                                                              // |
                                                               // |
function generateOuterYieldFrom(): Generator {                 // |
    // First yield values generated by generateIntegers1And2()    |
    yield from generateIntegers1And2();                        // *<---+
    // then yield integers 3                                           |
    yield 3;                                                     // <--+
    // and 4                                                           |
    yield 4;                                                     //  <-+
}                                                                //    |
                                                                 //    |
foreach (generateOuterYieldFrom() as $value) {                   //    |
    var_dump($value); // Shows 1, 2, 3 and 4                         ->*
}

function generateIntegers56AndReturn(): Generator {
    yield 5;                                                  // <---+
    yield 6;                                                  //  <--+
                                                              //     |
    return ["five", "six"];                       // <--+            |
}                                                 //    |            |
                                                  //    |            |
$gen = generateIntegers56AndReturn();             //    |            |
                                                  //    |            |
// Consume the values **yielded** by                    |            |
// generateIntegers56AndReturn()                        |            |
foreach ($gen as $value) {                        //    |            |
    var_dump($value); // Shows 5, then 6                |          ->*
}                                                 //    |
                                                  //    |
// Access the value **returned** by the generator       |
var_dump($gen->getReturn());                      //  ->*

function wtf(): Generator {
    return ["W", "T", "F", "!"];
    // Without the following line, PHP would complain with a TypeError:
    // Return value of wtf() must be an instance of Generator, array returned.
    // The presence of a yield keyword anywhere inside the function makes it a Generator.
    // However, since we return *before* reaching any *yield*, 42 is never yielded.
    // This is empty generator!
    yield 42;
}

$gen = wtf();

// This foreach loop is not entered!
foreach ($gen as $value) {
    var_dump($value);
}

// However, we can loop on the array *returned* by wtf():
foreach ($gen->getReturn() as $value) {
    echo $value; // Will print: WTF!
}

1
শেষ উদাহরণ, রিটার্নটি ফাংশন সম্পাদনকে "সমাপ্ত" করে, অর্থাৎ কোডটি ইয়েল্ড অর্জন করে না।
রদ্রিগো জারোচে

5

ডকুমেন্টেশন থেকে :

যে কোনও ফাংশন yieldরয়েছে একটি জেনারেটর ফাংশন।

সুতরাং yieldমৃত্যুদন্ড কার্যকর করা হয়েছে কিনা তা বিবেচ্য নয়, পার্সার এটি ফাংশন সংজ্ঞায় কোথাও দেখে এবং এটি একটি জেনারেটরে পরিণত করে।

যদি ফাংশনটি কখনই yieldবিবৃতিটি কার্যকর করে না , তবে জেনারেটর কোনও মান দেয় না। returnযখন আপনি ফলাফলটি ব্যবহার করার চেষ্টা করবেন তখন ফিরে আসা মানটিকে অগ্রাহ্য করা হবে। নথি বলছে:

দ্রষ্টব্য:
পিএইচপি 5-এ, একটি জেনারেটর কোনও মান ফিরিয়ে দিতে পারেনি: এটি করার ফলে একটি সংকলন ত্রুটি হবে। একটি খালি returnবিবৃতিটি একটি জেনারেটরের মধ্যে বৈধ সিনট্যাক্স ছিল এবং এটি জেনারেটরটি সমাপ্ত করবে। পিএইচপি .0.০ থেকে, একটি জেনারেটর মান ফিরিয়ে দিতে পারে, যা জেনারেটর :: getReturn () ব্যবহার করে পুনরুদ্ধার করা যেতে পারে ।

সুতরাং আপনি করতে পারেন:

$gen = generate();
foreach ($gen as $value) {
    echo $value;
}
print_r($gen->getReturn());
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.