IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> PHP:生成器语法 -> 正文阅读

[PHP知识库]PHP:生成器语法


生成器函数看起来像普通函数——不同的是普通函数返回一个值,而生成器可以 yield 生成多个想要的值。 任何包含 yield 的函数都是一个生成器函数。

当一个生成器被调用的时候,它返回一个可以被遍历的对象.当你遍历这个对象的时候(例如通过一个foreach循环),PHP 将会在每次需要值的时候调用对象的遍历方法,并在产生一个值之后保存生成器的状态,这样它就可以在需要产生下一个值的时候恢复调用状态。

一旦不再需要产生更多的值,生成器可以简单退出,而调用生成器的代码还可以继续执行,就像一个数组已经被遍历完了。

注意:

生成器能够返回多个值,通过 Generator::getReturn() 可以获取到。

yield关键字

生成器函数的核心是yield关键字。它最简单的调用形式看起来像一个return申明,不同之处在于普通return会返回值并终止函数的执行,而yield会返回一个值给循环调用此生成器的代码并且只是暂停执行生成器函数。

示例 #1 一个简单的生成值的例子

<?php
function gen_one_to_three() {
    for ($i = 1; $i <= 3; $i++) {
        //注意变量$i的值在不同的yield之间是保持传递的。
        yield $i;
    }
}

$generator = gen_one_to_three();
foreach ($generator as $value) {
    echo "$value\n";
}
?>

以上例程会输出:

1
2
3
注意:

在内部会为生成的值配对连续的整型索引,就像一个非关联的数组。

警告
传入 Generator::send() 的值会被赋值到 $data, 或者直接调用 Generator::next() 时,赋的值将是 null。

指定键名来生成值

PHP的数组支持关联键值对数组,生成器也一样支持。所以除了生成简单的值,你也可以在生成值的时候指定键名。

如下所示,生成一个键值对与定义一个关联数组十分相似。

示例 #2 生成一个键值对

<?php
/* 
 * 下面每一行是用分号分割的字段组合,第一个字段将被用作键名。
 */

$input = <<<'EOF'
1;PHP;Likes dollar signs
2;Python;Likes whitespace
3;Ruby;Likes blocks
EOF;

function input_parser($input) {
    foreach (explode("\n", $input) as $line) {
        $fields = explode(';', $line);
        $id = array_shift($fields);

        yield $id => $fields;
    }
}

foreach (input_parser($input) as $id => $fields) {
    echo "$id:\n";
    echo "    $fields[0]\n";
    echo "    $fields[1]\n";
}
?>

以上例程会输出:

1:
PHP
Likes dollar signs
2:
Python
Likes whitespace
3:
Ruby
Likes blocks
警告
和之前生成简单值类型一样,在一个表达式上下文中生成键值对也需要使用圆括号进行包围:

$data = (yield $key => $value);

生成 null 值

Yield 可以在没有参数传入的情况下被调用来生成一个 null 值并配对一个自动的键名。

示例 #3 生成nulls

<?php
function gen_three_nulls() {
    foreach (range(1, 3) as $i) {
        yield;
    }
}

var_dump(iterator_to_array(gen_three_nulls()));
?>

以上例程会输出:

array(3) {
[0]=>
NULL
[1]=>
NULL
[2]=>
NULL
}

使用引用来生成值

生成函数可以像使用值一样来使用引用生成。这个和从函数返回一个引用一样:通过在函数名前面加一个引用符号。

示例 #4 使用引用来生成值

<?php
function &gen_reference() {
    $value = 3;

    while ($value > 0) {
        yield $value;
    }
}

/* 
 * 我们可以在循环中修改 $number 的值,而生成器是使用的引用值来生成,所以 gen_reference() 内部的 $value 值也会跟着变化。
 */
foreach (gen_reference() as &$number) {
    echo (--$number).'... ';
}
?>

以上例程会输出:

2… 1… 0…

可用的 yield from 生成器委托

生成器委托允许使用 yield from 关键字从另外一个生成器、 Traversable 对象、array 通过生成值。 外部生成器将从内部生成器、object、array 中生成所有的值,直到它们不再有效, 之后将在外部生成器中继续执行。

如果生成器与 yield from 一起使用,那么 yield from 表达式将返回内部生成器返回的任何值。

警告
存储到 array (例如使用 iterator_to_array())
yield from 不能重置 key。它保留 Traversable 对象或者 array 返回的 key。因此,某些值可能会与其他的 yield 或者 yield from 共享公共的 key,因此,在插入数组时将会用这个 key 覆盖以前的值。

一个非常重要的常见情况是 iterator_to_array() 默认返回带 key 的 array , 这可能会造成无法预料的结果。 iterator_to_array() 还有第二个参数 use_keys ,可以设置为 false 来收集 Generator 返回的不带 key 的所有值。

示例 #5 使用 iterator_to_array() 的 yield from

<?php
 function inner() {
     yield 1; // key 0
     yield 2; // key 1
     yield 3; // key 2
 }
 function gen() {
     yield 0; // key 0
     yield from inner(); // keys 0-2
     yield 4; // key 1
 }
 // 传递 false 作为第二个参数获得数组 [0, 1, 2, 3, 4]
 var_dump(iterator_to_array(gen()));
 ?>

以上例程会输出:

array(3) {
[0]=>
int(1)
[1]=>
int(4)
[2]=>
int(3)
}

示例 #6 yield from 的基本用法

<?php
function count_to_ten() {
    yield 1;
    yield 2;
    yield from [3, 4];
    yield from new ArrayIterator([5, 6]);
    yield from seven_eight();
    yield 9;
    yield 10;
}

function seven_eight() {
    yield 7;
    yield from eight();
}

function eight() {
    yield 8;
}

foreach (count_to_ten() as $num) {
    echo "$num ";
}
?>

以上例程会输出:

1 2 3 4 5 6 7 8 9 10
示例 #7 yield from 并返回多个值

<?php
function count_to_ten() {
    yield 1;
    yield 2;
    yield from [3, 4];
    yield from new ArrayIterator([5, 6]);
    yield from seven_eight();
    return yield from nine_ten();
}

function seven_eight() {
    yield 7;
    yield from eight();
}

function eight() {
    yield 8;
}

function nine_ten() {
    yield 9;
    return 10;
}

$gen = count_to_ten();
foreach ($gen as $num) {
    echo "$num ";
}
echo $gen->getReturn();
?>

以上例程会输出:

1 2 3 4 5 6 7 8 9 10

该博文为原创文章,未经博主同意不得转。
本文章博客地址:https://cplusplus.blog.csdn.net/article/details/127122205

  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2022-10-08 20:21:33  更:2022-10-08 20:21:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/18 11:42:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码