이전에 IEnumerable과 yield를 다룰 때 잠깐 설명했었던 반복기의 개념을 알아보고자 한다.
우리가 자료구조를 관리함에 있어서, 배열이나 컬렉션을 순차적으로 순회하며 각각의 값에 접근할 수 있는 반복문인 Foreach문이 있는데, 이 기능은 IEnumerable 인터페이스를 상속받은 배열이 필요하다고 설명했었다.
그리고 이 foreach문을, 반복기라는 것이 해당 컬렉션을 순회하며 값을참조한다고 했었다.
반복기 Iterator는 자료구조에 저장되어있는 요소들을 순차적으로 접근하는 기능을 한다.
c#의 자료구조들은 대부분 반복기를 포함하고 있어 순회가 가능하고, 따라서 foreach문을 사용할 수 있다.
따라서 foreach문을 통한 순회검사는 자료구조의 종류나, 자료구조 내부의 구조가 어떻던지와는 무관하게 순회가 가능하다는 장점이 있다.
이렇게 반복기를 갖고있는 자료구조는 모두 IEnumerable 인터페이스를 상속받았다. 그렇다면 이것은 무엇일까?
IEnumerable 인터페이스는 상속받은 객체가 IEnumerator 인터페이스를 상속받은 객체를 포함할 것을 명시한다.
IEnumerator 인터페이스는, 반복기 객체들이 상속받는다.
즉, IEnumerable은 반복기를 갖고있어 내부순회가 가능한 자료구조라는 뜻이다.
이러한 반복기는 왜 사용하는 것일까?
반복기가 있음으로, 우리는 다양한 자료구조들의 순회를 자료구조의 종류와 내부구조와 무관하게 진행할 수 있다고 했다.
이에 대한 예를 들어보자.
우리가 배운 자료구조들 중, 많은 수가 배열 기반으로 이루어져 있지만, 그렇지 않은 자료구조도 존재한다.
우리가 배운 자료구조 중, Linked List가 이에 해당할 것이다.
또한, for문을 통해 반복시키고자 할 때, 원하는 값을 이끌어내지 못하는 자료구조도 있을 것이다.
예를들어, Queue는 머리에 해당하는 인덱스가 가장 먼저 나올 데이터인데 반해, Stack에서는 마지막 데이터가 가장 먼저 나올 데이터가 된다.
또. Queue는 순환형 구조로 되어있기 때문에 시작하는 지점의 인덱스가 매번 바뀐다.
이렇게 다양한 자료구조가 있고, 자료구조마다 다른 내부 구조적 특징을 전부 고려하여 for문을 사용하는 것은 굉장히 까다롭고 어려운 일일 것이다.
그러나, 반복기를 통한 foreach문을 통해 순회한다면, 이와는 상관 없이, IEnumerable인터페이스를 상속받은 자료구조라면 동일한 반복으로 순회가 가능하다.
이렇게 고마운 역할을 하는 반복기는 어떤 친구일지 더 자세히 알아보도록 하자.
반복기는 전에 설명했듯, 각 컬렉션의 위치를 가리키는 레이저 포인터같은 것이라고 했었다.
포인터의 개념과 같이, 반복기 역시 참조 변수이다. Linked List의 Node들을 떠올리면 좋을 것이다.
반복기는 각 배열(혹은 컬렉션)에 해당하는 값을 순서대로 가리킨다.
즉, 해당하는 값을 참조하여 그 값의 역참조 값을 반환할 수 있다.
for문에서는 우리가 직접 변수를 선언하고, 변수의조건과 증감식을 통해 제어해야했지만, foreach문은 그 기능을 간단하게 정리해줄 수 있다.
접근할 값의 자료형과, 반복기가 접근할 컬렉션만 입력한다면, 반복기가 입력한 컬렉션으로 들어가 내가 참조하길 원하는 자료형을 참조해준다.
다만, foreach가 for문보다 모든 면에서 앞서는 것은 아니다.
앞서 말했듯, for문을 통한 반복처럼, 조건을 사용자가 능동적으로 설정할 수 없다는 단점이 있다.
그리고, for문과는 다르게, foreach문은 순회하던 컬렉션이 foreach문 도중에 변경된다면 더이상 순회하지 못한다.
예를들어, 다음과 같은 foreach문이 있다고 가정해보자.
List<int> list = new List<int>(){0, 1, 2, 3, 4, 5};
foreach(int i in list)
{
list.Add(i + 1);
}
아래의 foreach문에서는, 각 값을 참조하여 해당하는 값에 1을 더한 값을 List에 추가하려고 했다.
그러나 이 때 문제가 생긴다.
foreach문에 전달했던 list의 크기가 foreach문을 진행하는 중에 바뀌어 버린 것이다.
list.Add()를 통해 list의 크기가 바뀌면, 반복기는 기존에 전달받은 컬렉션으로 들어갈 수 없게 되어 반복을 더이상 진행하지 못한다.
따라서 이에 유의해야한다.
'C# 일기' 카테고리의 다른 글
| 28. 정렬 알고리즘 (0) | 2024.03.26 |
|---|---|
| 26. List와 Linked List (0) | 2024.03.13 |
| 25. Queue (2) | 2024.03.12 |
| 24. Stack (0) | 2024.03.12 |
| 23. IEnumerable과 yield (0) | 2024.03.12 |