首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP SPL ArrayIterator v简单的foreach

PHP SPL ArrayIterator v简单的foreach
EN

Stack Overflow用户
提问于 2012-05-29 06:07:06
回答 2查看 2.9K关注 0票数 5

好的,正如标题所说:使用ArrayIterator而不是简单的foreach循环的主要好处是什么。

我有一个被用作容器的对象,它的主要职责是存储一个对象数组。

有人建议我让我的类实现IteratorAggregate,并返回一个包含对象数组的ArrayIterator,如下所示:

代码语言:javascript
复制
  public function getIterator()
  {  
    return new ArrayIterator($this->_objs);  
  }

我看不到这样做有什么好处,而不是简单地返回数组,然后使用标准的foreach循环它们。

有人能解释一下为什么这是个好主意吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-05-29 10:15:41

返回数组会公开对象的内部结构。使用迭代器更加抽象。

我不知道你的类是做什么的,或者哪一个更适合你的情况。但作为一般经验法则,如果唯一实际的用例是迭代数据,那么您应该返回迭代器。

票数 -2
EN

Stack Overflow用户

发布于 2013-12-16 00:34:55

实现数组的好处很简单:您可以访问整个对象,或者只访问一个非常具体的、甚至是private属性作为数组。

在这个非常简单的示例中,我们使用IteratorArrayAccess来访问名为$array的特定属性。

代码语言:javascript
复制
class Foo implements \ArrayAccess, \Iterator
{
    public $pointer = 0;

    private $array = [
        'first value',
        'second value',
        'third value',
    ];

    public function __construct()
    {
        $this->pointer = 0;
    }

    public function current()
    {
        return $this->array[ $this->pointer ];
    }

    public function key()
    {
        return $this->pointer;
    }

    public function next()
    {
        ++$this->pointer;
    }

    public function rewind()
    {
        $this->pointer = 0;
    }

    public function valid()
    {
        return isset( $this->array[ $this->position ] );
    }
}

我们现在可以像遍历每个数组一样遍历它:

代码语言:javascript
复制
$foo = new Foo();
foreach ( $foo as $key => $value )
{
    print "Index: {$key} - Value: {$value}".PHP_EOL;
}

正如在上一个例子中所看到的,我们需要实现所有这些方法,以便循环到低谷,并访问已经存在的数据。要实现允许我们实际设置值的ArrayAccess,我们必须实现另一组方法:

代码语言:javascript
复制
ArrayAccess {
    abstract public boolean offsetExists ( mixed $offset )
    abstract public mixed offsetGet ( mixed $offset )
    abstract public void offsetSet ( mixed $offset , mixed $value )
    abstract public void offsetUnset ( mixed $offset )
}

现在,通过简单地使用IteratorAggregate,我们可以完全避免编写和重复(current/key/next/ set )方法集。这将把它成一个强制的方法getIterator()

现在我们有了一个结果类,如下所示:

代码语言:javascript
复制
class Bar implements \ArrayAccess, \IteratorAggregate
{
    private $array = [];

    public function getIterator()
    {
        return new ArrayIterator( $this->array );
    }
}

并且我们拥有对类$array属性的完全数组访问权限。我们可以设置和取消设置值,检查它们是否返回isset,可以遍历它们等等,非常方便。它和上面的所有8个方法做的事情完全一样,只是通过实现IteratorAggregate

最后要注意的是:您可能还要再做一步并实现Traversable。这个接口非常好用,因为它允许您强制实现IteratorIteratorAggregate,而无需明确说明实现开发人员需要使用哪一个。它只是解释了强制要求对象必须是可循环的。

代码语言:javascript
复制
$foo = new IteratorContainerController();
$foo->addDependency( Traversable $bar );

这意味着IteratorContainerController()的依赖项将始终是IteratorIteratorAggregate实现的对象。因此,有人可以简单地抛出一个IteratorAggregate,或者,如果他/他需要更细粒度的控制,或者在设置变量之前对变量进行预处理,他/他可以简单地使用Iterator

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10790885

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档