Iterable và Iterator
Thuộc phần Lập trình hướng đối tượng trong hành trình Dart của Coddy. Bài học 68 trên 110.
Mỗi khi dùng vòng lặp for-in với List, Set hoặc bộ sưu tập khác, bên dưới bạn đang làm việc với Iterable và Iterator. Hiểu các khái niệm này giúp bạn tạo các lớp của riêng mình để có thể lặp qua.
Đối tượng Iterable là bất kỳ đối tượng nào có thể tạo ra một chuỗi giá trị. Đối tượng này có một yêu cầu chính: getter iterator trả về một Iterator. Iterator thực sự duyệt qua từng phần tử một:
var numbers = [1, 2, 3];
var iterator = numbers.iterator;
while (iterator.moveNext()) {
print(iterator.current); // 1, rồi đến 2, rồi đến 3
}Phương thức moveNext() chuyển đến phần tử tiếp theo và trả về true nếu còn phần tử, hoặc false khi đã hết. Thuộc tính current cho bạn biết phần tử hiện tại.
Để lớp của bạn có thể lặp qua được, hãy triển khai giao diện 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
}
}Giờ đây, Countdown hoạt động với vòng lặp for-in và mọi phương thức của Iterable như map, where và fold. Đây là mẫu thiết yếu khi tạo các bộ sưu tập tùy chỉnh tích hợp liền mạch với hệ sinh thái bộ sưu tập của Dart.
Thử thách
DễHãy tạo một bộ sinh dãy số tùy chỉnh có thể duyệt bằng vòng lặp for-in! Bạn sẽ tự tạo các lớp Iterable và Iterator để sinh một dãy số trong phạm vi đã chỉ định.
Bạn sẽ sắp xếp code thành hai tệp:
range.dart: Tạo hai lớp phối hợp với nhau để tạo ra một dãy số:- Lớp
RangeIteratortriển khaiIterator<int>. Lớp này cần theo dõi vị trí hiện tại và xác định khi nào cần dừng. Trình lặp bắt đầu ở vị trí trước phần tử đầu tiên, vì vậy phải gọimoveNext()trước khi truy cậpcurrent. - Lớp
Rangemở rộngIterable<int>. Lớp này nhận giá trịstartvàendtrong hàm khởi tạo, đồng thời cung cấp getteriteratortrả về mộtRangeIterator.
startvàend. Ví dụ,Range(1, 5)sẽ tạo ra: 1, 2, 3, 4, 5.- Lớp
main.dart: Nhập tệp range của bạn và minh họa iterable tùy chỉnh:- Tạo
Range(1, 5)và dùng vòng lặpfor-inđể in từng số trên một dòng riêng - In ra một dòng trống
- Tạo
Range(10, 13)và dùng phương thứcmapđể nhân đôi từng giá trị, sau đó in danh sách kết quả
- Tạo
Vì lớp Range mở rộng Iterable, lớp này tự động có quyền sử dụng tất cả các phương thức tập hợp mạnh mẽ như map, where và fold. Đó chính là ưu điểm của việc triển khai giao diện Iterable!
Đầu ra dự kiến:
1
2
3
4
5
[20, 22, 24, 26]Tự làm thử
import 'range.dart';
void main() {
// TODO: Tạo Range(1, 5) và dùng vòng lặp for-in để in ra từng số
// TODO: In ra một dòng trống
// TODO: Tạo Range(10, 13), dùng map để nhân đôi từng giá trị rồi in ra danh sách
}
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Lập trình hướng đối tượng
1Nền tảng về lập trình hướng đối tượng
Tệp bên ngoàiThư viện và câu lệnh importGiới thiệu về lập trình hướng đối tượngLớp và đối tượngTừ khóa thisPhương thứcBiến thể hiệnKiến thức cơ bản về hàm khởi tạoÔn tập: Máy tính đơn giản4An toàn với giá trị null
Giới thiệu về an toàn với giá trị nullCó thể null và không thể nullToán tử ? và !Từ khóa late và an toàn với giá trị nullToán tử xử lý nullAn toàn với giá trị null trong lớpÔn tập: hệ thống hồ sơ người dùng7Lớp trừu tượng và interface
Lớp trừu tượngPhương thức trừu tượngInterface trong DartInterface ngầm địnhTriển khai và kế thừaNhiều interfaceÔn tập: Máy tính hình10Bộ sưu tập và kiểu tổng quát
Tổng quan về List, Set và MapBộ sưu tập an toàn về kiểuLớp tổng quátPhương thức tổng quátRàng buộc kiểu tổng quátIterable và IteratorÔn tập: Lưu trữ tổng quát2Hàm khởi tạo trong Dart
Hàm khởi tạo mặc địnhHàm khởi tạo có tênDanh sách khởi tạoHàm khởi tạo hằng sốHàm khởi tạo nhà máyHàm khởi tạo chuyển hướngÔn tập: Trình tạo hình dạng5Đóng gói
Thành viên công khai và riêng tưQuy ước tiền tố _Tính riêng tư ở cấp thư việnTìm hiểu sâu về getter và setterChe giấu thông tinÔn tập: hồ sơ học sinh8Mixin
Giới thiệu về MixinTạo MixinSử dụng nhiều MixinTừ khóa on trong MixinMixin và kế thừaMixin và giao diệnÔn tập: hệ thống động vật3Thuộc tính của lớp
Thành viên instance và thành viên tĩnhTrường final và constBiến latePhương thức và trường tĩnhGetter và setterÔn tập: trình quản lý tài khoản ngân hàng6Kế thừa
Kế thừa cơ bảnTừ khóa superGhi đè phương thứcChú thích @overrideTừ khóa lớp finalHàm khởi tạo và kế thừaÔn tập: phân cấp nhân viên9Đa hình
Khái niệm cơ bản về đa hìnhĐa hình qua giao diệnKiểm tra kiểu lúc chạyToán tử is và asTừ khóa hiệp biếnÔn tập: Bộ xử lý thanh toánTự luyện tập: Trình biên dịch Dart online