PHP迭代器:Iterator和IteratorAggregate
使用迭代模式遍历所有的对象的时候,都必须实现Traversable(遍历)接口。但是Traversable是一个内部的类,只有用c语言编写的类才可以实现Traversable实现。如果我们在自定义的 类中实现它,会报错。那么我们要实现对象的遍历,就必须通过Iterator或者IteratorAggregate接口实现Traversable接口。
一,首先说说Iterator接口
它是在c语言中定义的,都是抽象方法,所以我们在实现接口的时候,就必须定义这些方法,代码如下:
Iterator extends Traversable {
/* 方法 */
abstract public mixed current ( void )
abstract public scalar key ( void )
abstract public void next ( void )
abstract public void rewind ( void )
abstract public boolean valid ( void )
}
接着我们在PHP中实现接口Iterator,代码如下:
//自定义类实现接口Iterator
class myIterator implements Iterator {
private $position = 0;
private $array = array(
"firstelement",
"secondelement",
"lastelement",
); public function __construct() {
$this->position = 0;
}
//定义rewind()-将数组指针移动到数组的开头位置
function rewind() {
var_dump(__METHOD__);
$this->position = 0;
}
//定义current()-返回当前的值
function current() {
var_dump(__METHOD__);
return $this->array[$this->position];
}
//定义可以key()-返回当前的键值
function key() {
var_dump(__METHOD__);
return $this->position;
}
//定义next()-将数组指针向前进一位指向下一个数组元素
function next() {
var_dump(__METHOD__);
++$this->position;
}
//定义valid()-确定当前元素是否存在,并且必须在next()和rewind()方法之后才可以调用
function valid() {
var_dump(__METHOD__);
return isset($this->array[$this->position]);
}
} $it = new myIterator; foreach($it as $key => $value) {
var_dump($key, $value);
echo "\n";
}
代码运行结果如下:
大家可能不明白,为什么利用foreach()就可以循环打印出类的属性,程序执行的顺序看我的注释,再次提醒大家注意
“定义valid()-确定当前元素是否存在,并且必须在next()和rewind()方法之后才可以调用”。
string(18) "myIterator::rewind" ----------程序开始执行首先调用rewind()函数,将数组指针移到数组开头位置
string(17) "myIterator::valid" ----------接着调用valid()当前元素是否存在,这个函数每次紧跟rewind()和next()函数被调用
string(19) "myIterator::current" ----------调用current()获取当前的值
string(15) "myIterator::key" ----------调用key()获取当前位置的键值
int(0)
string(12) "firstelement"
string(16) "myIterator::next" ----------上一步获取当前位置,肯定要调用next(),获取下一个位置的指针,即指针向下移动
string(17) "myIterator::valid" ----------判断当前元素是否存在
string(19) "myIterator::current" ----------如果存在,获取当前元素
string(15) "myIterator::key" ----------获取当前键值,为了下一步指针向前移动
int(1)
string(13) "secondelement"
string(16) "myIterator::next" ---------指针指向下一个元素
string(17) "myIterator::valid" ---------判断当前元素是否存在
string(19) "myIterator::current" ---------元素存在,获取当前的元素
string(15) "myIterator::key" ---------获取当前键值
int(2)
string(11) "lastelement"
string(16) "myIterator::next" ---------指针指向下一个位置
string(17) "myIterator::valid" ---------判断当前位置是否有值。如果有获取值,没有就结束遍历
二 ,IteratorAggregate接口
是用来将Iterator接口要求实现的5个方法委托给其他类(比如ArrayIterator)来实现
(1) ArrayIterator接口:允许从PHP数组中创建一个迭代器。上面我们通过实现Iterator接口实现迭代器,但是ArrayIterator可以直接跳过,实现同样的功能。
(2)当ArrayIterator迭代器和IteratorAggregate类一起使用的时候,直接免去Iterator创建方法的工作,所以在实现IteratorAggregate类中的方法getIterator时候,返回一个ArrayIterator接口就好。
(3) IteratorAggregate的c语言实现代码:定义抽象方法getIterator,所以实现接口的时候,必须定义该方法
IteratorAggregate extends Traversable {
/* 方法 */
abstract public Traversable getIterator ( void )
}
class myData implements IteratorAggregate {
public $property1 = "Public property one";
public $property2 = "Public property two";
public $property3 = "Public property three";
public function __construct() {
$this->property4 = "last property";
}
//定义方法----getIterator()---返回一个Iterator类的实例
public function getIterator() {
//ArrayIterator()接口可以创建一个Iterator实例
return new ArrayIterator($this);
}
}
$obj = new myData();
foreach($obj as $key => $value) {
var_dump($key, $value);
echo "\n";
}
运行如下:
string(9) "property1"
string(19) "Public property one"
string(9) "property2"
string(19) "Public property two"
string(9) "property3"
string(21) "Public property three"
string(9) "property4"
string(13) "last property"
PHP迭代器:Iterator和IteratorAggregate的更多相关文章
- 用struts2标签如何从数据库获取数据并在查询页面显示。最近做一个小项目,需要用到struts2标签从数据库查询数据,并且用迭代器iterator标签在查询页面显示,可是一开始,怎么也获取不到数据,想了许久,最后发现,是自己少定义了一个变量,也就是var变量。
最近做一个小项目,需要用到struts2标签从数据库查询数据,并且用迭代器iterator标签在查询页面显示,可是一开始,怎么也获取不到数据,想了许久,最后发现,是自己少定义了一个变量,也就是var变 ...
- VC++ 迭代器 iterator, const_iterator, const iterator
迭代器 iterator, const_iterator, const iterator 迭代器iterator的作用类似于指针. (1)iterator只有针对制定<类型>的容器才有效. ...
- 迭代器iterator
现在接着上篇的,写一来标识vector 的元素的对象迭代器iterator: 还是通过具体代码举例: 下面我讲了一个我暑期团队的故事哦~~: #include<iostream> #inc ...
- c++中的迭代器 iterator
迭代器iterator的作用类似于指针. iterator只有针对制定<类型>的容器才有效.例如: vector<int> vec; vector<int>::it ...
- Python的迭代器(iterator)和生成器(constructor)
一.迭代器(iterator) 1.迭代器的概述 在Python中,for循环可以用于Python中的任何类型,包括列表.元祖等等,实际上,for循环可用于任何“可迭代对象”,这其实就是迭代器 迭代器 ...
- 设计模式 - 迭代模式(iterator pattern) Java 迭代器(Iterator) 详细解释
迭代模式(iterator pattern) Java 迭代器(Iterator) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 參考迭代器模式(ite ...
- Java 实现迭代器(Iterator)模式
类图 /** * 自己定义集合接口, 相似java.util.Collection * 用于数据存储 * @author stone * */ public interface ICollection ...
- C++迭代器 iterator【转】
1. 迭代器(iterator)是一中检查容器内元素并遍历元素的数据类型.(1) 每种容器类型都定义了自己的迭代器类型,如vector:vector<int>::iterator iter ...
- Java迭代器Iterator
之前我们实现了迭代器模式,很多编程语言实际上已经内置了迭代器类,比如Java就为我们实现了迭代器Iterator.我们首先来看Iterator中的源码. 通过JDK源码我们发现Iterator是一个接 ...
随机推荐
- openstack搭建之-neutron配置(11)
一.base节点设置 mysql -u root -proot CREATE DATABASE neutron; GRANT ALL PRIVILEGES ON neutron.* TO 'neutr ...
- Flask —— 信号(5)
Flask框架中的信号基于blinker,其主要就是让开发者可是在flask请求过程中定制一些用户行为. pip3 install blinker 1. 内置信号 request_started = ...
- centos7 docker安装
Docker分为社区版CE和企业版EE. 社区版是免费提供给个人开发者和小型团体使用的,企业版会提供额外的收费服务,比如经过官方测试认证过的基础设施.容器.插件等 社区版按照stable和edge两种 ...
- python之路6-迭代器、生成器、装饰器
1.迭代器&生成器 列表生成式 现在有个需求,列表[1,2,3,4,5,6,7,,8,9],要求把列表里的每个值加1,如何实现? 方法一: list = [1,2,3,4,5,6,7,8,9] ...
- IO多路复用和local概念
一.local 在多个线程之间使用threading.local对象,可以实现多个线程之间的数据隔离 import time import random from threading import T ...
- Vue——报错总结
[Vue warn]: Cannot find element: #app [报错原因] 1. 把对应js放在了head标签里面,页面没有加载完成就进行渲染,导致找不到#app. 2.加了<te ...
- 使用@property
@property装饰器就是负责把一个方法变成属性调用的,既能检查参数,又可以用类似属性这样简单的方式来访问类的变量 class Student(object): @property def scor ...
- Linux-服务器创建swap交换分区
服务器 swap 交换分区制作 作用:‘提升‘ 内存的容量,防止OOM(Out Of Memory) 查看当前的交换分区 # cat /proc/swaps # free -m # swapon -s ...
- SQL中GROUP BY用法示例(转)
工作中又用到了写SQL 好多年不用了 再拿过来温习下: 不觉豁然开朗 概述 GROUP BY我们可以先从字面上来理解,GROUP表示分组,BY后面写字段名,就表示根据哪个字段进行分组,如果有用Exce ...
- JAVA传递带有空格的参数
String s="b2 + b1"; Process child = Runtime.getRuntime().exec("C:\\eclipse-workspace\ ...