데이터 구조 기반 반복
리스트의 요소를 하나씩 꺼내 쓰는 반복문은 끝을 어떻게 알까?
반복자
요소의 수만큼 돕니다
데이터 구조 기반 반복은 데이터 구조에 든 요소의 수가 반복 횟수를 정합니다. 제어는 반복자(iterator)가 맡습니다. 부를 때마다 정해진 순서로 다음 요소를 내주고, 더 줄 요소가 없으면 반복이 끝납니다.
데이터 구조는 배열이나 리스트처럼 값 여러 개를 담는 것이고, 요소는 거기 든 값 하나입니다. 이름 셋은 이 강의가 따르는 교재의 예제에 나오는 값입니다.
C의 for로 만든 반복자
세 식이 시작, 검사, 다음을 맡습니다
C에는 반복자가 따로 없지만 for로 직접 만들 수 있습니다. 첫째 식에서 시작 지점을 잡고, 둘째 식에서 끝인지 검사하고, 셋째 식에서 다음 요소로 옮겨 갑니다.
연결 리스트(값을 화살표로 줄줄이 이은 구조)를 도는 예입니다. p는 요소의 위치를 담는 포인터, p->next는 그다음 요소, NULL은 '더 없음'입니다.
PHP의 배열 반복
가리키고, 옮기고, 되돌립니다
PHP는 배열을 도는 데 쓰는 내장 함수를 줍니다. current는 지금 요소를 가리키고, next는 다음 요소로 옮기고, reset은 첫 요소로 되돌립니다. 이 셋을 조합해 배열을 돕니다.
내장 함수는 언어가 미리 만들어 둔 함수입니다. 배열의 값은 예시입니다.
Java와 C#의 foreach
foreach가 꺼내 줍니다
Java 5.0의 for는 콜론 오른쪽 컬렉션에서 요소를 하나씩 꺼내 왼쪽의 루프 변수에 넣습니다. 낱말은 for지만 foreach라고 부릅니다. C#과 F# 같은 .NET 언어에는 foreach 문이 따로 있습니다.
컬렉션은 배열, 리스트, 스택, 큐처럼 요소를 모아 둔 것입니다. 직접 만든 컬렉션도 반복자를 내주기로 약속한 타입(Java의 Iterable, C#의 IEnumerator)을 구현하면 이렇게 돕니다.
Ruby의 블록
블록을 붙이면 메서드가 반복자가 됩니다
Ruby에서는 중괄호나 do와 end로 감싼 코드 덩어리를 블록(block)이라고 합니다. 블록을 메서드 호출 뒤에 붙이면 그 메서드가 반복자 구실을 합니다. times, each, upto가 미리 정의된 반복자 메서드입니다.
메서드는 값에 딸린 함수입니다. 세로 막대 사이의 |value|는 블록이 요소를 받는 이름입니다. list의 값은 예시입니다.
yield
멈춘 자리에서 이어서 실행합니다
Python의 yield는 return처럼 값을 돌려주지만 함수를 끝내지 않습니다. 다음에 부르면 처음이 아니라 멈췄던 자리에서 이어서 실행합니다. 이전 상태를 기억하므로 부를 때마다 다음 값을 내주는 반복자가 됩니다.
i += 1은 i를 1 늘립니다. Ruby의 yield는 조금 달라서, 메서드가 뒤에 붙은 블록을 호출하며 값을 넘깁니다.
다음 편