프로그래밍 언어론 6-5-3강. 반복자(Iterators)

[프로그래밍 언어론]

2019. 12. 1. 12:54

 

[반복자(Iterators)]

: 앞서 보았던 예제들은 산술 시퀀스의 원소들에 대한 for 루프 반복자였다.

: 여기서는 well-defined set(collection, 객체지향의 class 인스턴스등) 의 요소들에 대한 반복.

: 객체 지향적 프로그래밍 기준으로 배열이나 그와 유사한 자료구조의 내부요소를 순회하는 객체를 의미

# JAVA : iterator에서 hasNext()를 이용해 내부요소 순회하는게 대표적인 예시

 

 

 

[True Iterators(진정한 반복자)]

: Clu, Python, Ruby, C#은 모든 추상 컨테이너가 그들의 아이템들을 열거될 수 있는 iterator을 제공한다.

: 반복자는 각 loop index를 제공하는 yield statements(상태 기록용)를 포함하는 서브루틴과 유사하다.

: For 루프들은 반복자로의 호출을 포함하도록 설계된다.

 

# 기존의 for loop문 예시 - Modula-2

FOR i := first TO last BY step DO

  ...

END

# 반복자를 이용한 for문 - Python

for i in range(first, last, step):

: 호출되면, 반복자는 yield statement를 실행해 메인 프로그램에 return하는 loop의 첫번째 index 값을 계산한다.

: 이후, yield에 더이상 element들이 없으면 반복자는 loop문을 종료한다.


 

 

[파이썬에서의 True Iterators]

: 사실상, 반복자는 별도의 제어 스레드로, 자체 프로그램 카운터를 가지고 있으며, 반복자의 실행은 index 값을 제공하는 for loop의 실행과 연동된다.

: 반복자 매커니즘은 코드에서 사용되는 원소들을 열거하는데 필요한 알고리즘을 "분리(decouple)" 역할을 한다.

: Python에서 범위 반복자(range iterator)은 선 정의(predefined) 된다.

 

# 이진트리의 노드들을 미리 열거해놓기 위한 파이썬 반복자(실례)

class BinTree:

  def __init__(self):  # constructor

    self.data = self.lchild = self.rchild = None

 

  def preorder(self):

    if self.data != None:

      yield self.data     # yield statement : return과 같은 개념. 하지만 상태를 기억하고 있는 상태.

    if self.lchild != None:

      for d in self.lchild.preorder():

        yield d

    if self.rchild != None:

      for d in self.rchild.preorder():

        yield d

: 파이썬은 동적 타입이기때문에, 이 코드는 어떤 data에서든 동작할 것이다. (정적 타입 언어일경우 일반화(generic) 필요)

 

 

 

[반복자 객체(Iterator Objects)]**

: 반복은 for loop의 특별한 형태와 loop를 위한 값들을 열거하는 매커니즘을 둘다 포함하고 있다.

: Eucild, C++, Java, Ada2012들은 파이썬을 연상시키는 Enumeration-controlled loops을 제공(True iterator 흉내)한다.

  - yield statement 없음 

  - 열거 값들을 위한 별도의 thread 비슷한 문맥 없음

  - 반복자는 초기화 방법, 다음 지수 값의 생성 방법, 완료 테스트 방법을 제공하는 일반 객체

  - 호출들의 사이에, 반복자의 상태가 객체의 데이터 멤버들 안에 유지되어야 한다.

 

# Java에서의 반복자 객체 (True iterator 모습을 흉내낸것)

Bintree<Interger> myTree = ...

# Iterator 구현되있을때 가능한 표현 방법, syntactic sugar 사용한 모습

# for(Iterator<Integer> it = myTree.iterator(); it.hasNext();) { Integer i = it.next(); ... 의 형태였음

for (Integer i : myTree) {  

  System.out.println(i);

}

: Java iterator는 요구되는 collection에 대한 연속적인 요소를 생산하는 방법더이상 없을때 나타내는 방법을 가지고 있다.

 

# C++에서의 반복자 객체

tree node* my_tree = ...

for (int n : *my_tree) P

  cout << n << "\n";

}

: C++ iterator는 포인터의 특별한 종류로써 동작하게끔 설계된다.