php - 生成器和数组有什么区别?

标签 php arrays iterator generator

今天 PHP 团队发布了 PHP 5.5.0版本,其中包括对生成器 的支持。读书the documentation ,我注意到它的作用与数组完全相同。

PHP 团队生成器示例:

// Only PHP 5.5
function gen_one_to_three() {
    for ($i = 1; $i <= 3; $i++) {
        // Note that $i is preserved between yields.
        yield $i;
    }
}

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

结果:

1
2
3

但我可以使用数组做同样的事情。而且我仍然可以与早期版本的 PHP 保持兼容。

看看:

// Compatible with 4.4.9!
function gen_one_to_three() {
    $results = array();
    for ($i = 1; $i <= 3; $i++) {
        $results[] = $i;
    }

    return $results;
}

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

那么问题来了:这个新特性存在的目的是什么?我必须在不使用新功能的情况下播放所有文档示例,将其替换为数组。

谁能给出一个很好的解释,也许还有一个例子,旧版本不一定不可能,但使用生成器可以帮助开发?

最佳答案

区别在于效率。例如,除 PHP 之外的许多语言都包括两个 range 函数,range()xrange()。这是生成器以及为什么要使用它们的一个很好的例子。让我们构建我们自己的:

function range($start, $end) {
    $array = array();
    for ($i = $start; $i <= $end; $i++) {
        $array[] = $i;
    }
    return $array;
}

现在这真的很简单。但是,对于大范围,它需要大量内存。如果我们尝试使用 $start = 0$end = 100000000 运行它,我们可能会耗尽内存!

但是如果我们使用生成器:

function xrange($start, $end) {
    for ($i = $start; $i <= $end; $i++) {
        yield $i;
    }
}

现在我们使用常量内存,但仍然有一个“数组”(如结构),我们可以在同一空间中迭代(并与其他迭代器一起使用)。

它不会替换数组,但它确实提供了一种避免需要内存的有效方法...

但它还可以节省项目的生成。由于每个结果都是按需生成的,因此您可以延迟执行(获取或计算)每个元素,直到您需要为止。因此,例如,如果您需要从数据库中获取一个项目并对每一行进行一些复杂的处理,您可以使用生成器延迟它,直到您真正需要该行:

function fetchFromDb($result) {
    while ($row = $result->fetchArray()) {
        $record = doSomeComplexProcessing($row);
        yield $record;
    }
}

因此,如果您只需要前 3 个结果,则只需处理前三个记录。

有关更多信息,我写了一篇 blog post关于这个确切的主题。

关于php - 生成器和数组有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17223802/

相关文章:

php - 通过php mysql从低到高和从高到低排序

php - 我如何优化这些查询?

python - 从字符串中提取二维列表

ruby-on-rails - Ruby 将两个数组合并为一个

java - 迭代实现 Iterable<Item> 的类中数组的非空部分

php - "sudo -u www-data git pull"凭证保存?

PHP LaTeX 到 PDF 的转换/编译

c# - Array.Length 和 Array.Count() 之间的区别

c++ - 迭代器 (string::iterator) 的行为是否超出范围?

java - ArrayList 最后一个索引