Iterable과 Iterator
Coddy Dart 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 110개 중 68번째.
List, Set 또는 다른 컬렉션에서 for-in 루프를 사용할 때마다, 여러분은 내부적으로 Iterable과 Iterator를 사용하고 있는 것입니다. 이러한 개념을 이해하면 반복 가능한 자신만의 클래스를 만들 수 있습니다.
Iterable은 일련의 값을 생성할 수 있는 모든 객체입니다. 여기에는 한 가지 핵심 요구 사항이 있습니다. 바로 Iterator를 반환하는 iterator 게터(getter)입니다. Iterator는 실제로 요소를 하나씩 훑으며 이동하는 역할을 합니다:
var numbers = [1, 2, 3];
var iterator = numbers.iterator;
while (iterator.moveNext()) {
print(iterator.current); // 1, 그 다음 2, 그 다음 3
}moveNext() 메서드는 다음 요소로 이동하며, 요소가 있으면 true를 반환하고 완료되면 false를 반환합니다. current 속성은 현재 요소를 제공합니다.
자신만의 클래스를 반복 가능하게 만들려면 Iterable 인터페이스를 구현하세요:
class Countdown extends Iterable<int> {
final int start;
Countdown(this.start);
@override
Iterator<int> get iterator => CountdownIterator(start);
}
class CountdownIterator implements Iterator<int> {
int _current;
CountdownIterator(int start) : _current = start + 1;
@override
int get current => _current;
@override
bool moveNext() {
if (_current > 0) {
_current--;
return true;
}
return false;
}
}
void main() {
for (var n in Countdown(3)) {
print(n); // 3, 2, 1, 0
}
}이제 Countdown은 for-in 루프 및 map, where, fold와 같은 모든 Iterable 메서드와 함께 작동합니다. 이 패턴은 Dart의 컬렉션 생태계와 원활하게 통합되는 커스텀 컬렉션을 구축할 때 필수적입니다.
챌린지
쉬움for-in 루프를 사용하여 반복할 수 있는 커스텀 범위 생성기를 만들어 봅시다! 지정된 범위 내의 숫자 시퀀스를 생성하기 위해 직접 Iterable 및 Iterator 클래스를 만들게 됩니다.
코드를 두 개의 파일로 구성합니다:
range.dart: 숫자 시퀀스를 생성하기 위해 함께 작동하는 두 개의 클래스를 만듭니다:Iterator<int>를 구현하는RangeIterator클래스. 이 클래스는 현재 위치를 추적하고 언제 멈춰야 할지 알아야 합니다. 반복자(iterator)는 첫 번째 요소 이전에서 시작하므로,current에 접근하기 전에moveNext()가 호출되어야 합니다.Iterable<int>를 상속받는Range클래스. 생성자에서start와end값을 받으며,RangeIterator를 반환하는iterator게터(getter)를 제공합니다.
start와end를 모두 포함해야 합니다. 예를 들어,Range(1, 5)는 1, 2, 3, 4, 5를 생성해야 합니다.main.dart: range 파일을 임포트하고 커스텀 iterable을 시연합니다:Range(1, 5)를 생성하고for-in루프를 사용하여 각 숫자를 개별 줄에 출력합니다.- 빈 줄을 하나 출력합니다 (
''). Range(10, 13)을 생성하고map메서드를 사용하여 각 값을 두 배로 만든 다음, 결과 리스트를 출력합니다.
Range 클래스가 Iterable을 상속받기 때문에, map, where, fold와 같은 강력한 컬렉션 메서드들을 자동으로 사용할 수 있게 됩니다. 이것이 바로 Iterable 인터페이스를 구현하는 것의 장점입니다!
예상 출력:
1
2
3
4
5
[20, 22, 24, 26]치트 시트
Iterable은 일련의 값을 생성할 수 있는 모든 객체를 의미합니다. 이는 Iterator를 반환하는 iterator 게터(getter)를 필요로 합니다.
Iterator는 다음을 사용하여 요소를 하나씩 이동합니다:
moveNext()- 다음 요소로 이동하며, 요소가 있으면true를, 끝에 도달하면false를 반환합니다.current- 현재 요소를 제공하는 속성입니다.
반복자(iterator)를 수동으로 사용하기:
var numbers = [1, 2, 3];
var iterator = numbers.iterator;
while (iterator.moveNext()) {
print(iterator.current); // 1, then 2, then 3
}사용자 정의 클래스를 반복 가능하게 만들려면, Iterable 인터페이스를 구현하고 그에 대응하는 Iterator 클래스를 생성하세요:
class Countdown extends Iterable<int> {
final int start;
Countdown(this.start);
@override
Iterator<int> get iterator => CountdownIterator(start);
}
class CountdownIterator implements Iterator<int> {
int _current;
CountdownIterator(int start) : _current = start + 1;
@override
int get current => _current;
@override
bool moveNext() {
if (_current > 0) {
_current--;
return true;
}
return false;
}
}
void main() {
for (var n in Countdown(3)) {
print(n); // 3, 2, 1, 0
}
}Iterable을 확장하는 클래스는 for-in 루프와 함께 작동하며 map, where, fold와 같은 모든 Iterable 메서드에 자동으로 접근할 수 있게 됩니다.
직접 해보기
import 'range.dart';
void main() {
// TODO: Range(1, 5)를 생성하고 for-in 루프를 사용하여 각 숫자를 출력하세요
// TODO: 빈 줄을 출력하세요
// TODO: Range(10, 13)을 생성하고, map을 사용하여 각 값을 두 배로 만든 후 리스트를 출력하세요
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.