Tìm hiểu về bao đóng
Thuộc phần Logic và luồng điều khiển trong hành trình Dart của Coddy. Bài học 46 trên 65.
Closure là một loại hàm đặc biệt có khả năng “ghi nhớ” các biến từ nơi nó được tạo ra, ngay cả khi ngữ cảnh ban đầu đã chạy xong. Hãy hình dung nó như một hàm mang theo một phần nơi nó ra đời đến bất cứ đâu.
Khi bạn tạo một hàm bên trong một hàm khác, hàm bên trong có thể truy cập các biến của hàm bên ngoài. Đây là một closure vì quyền truy cập này vẫn còn ngay cả sau khi hàm bên ngoài chạy xong.
Function createGreeting(String name) {
return () {
return "Hello, $name!";
};
}Trong ví dụ này, hàm ẩn danh mà createGreeting trả về là một closure. Hàm này lưu giữ tham số name từ phạm vi bao quanh nó. Ngay cả khi createGreeting chạy xong, hàm được trả về vẫn nhớ giá trị của name.
Closure rất hữu ích để tạo các hàm chuyên biệt hoặc duy trì trạng thái một cách gọn gàng. Closure cho phép bạn xây dựng các hàm được tùy chỉnh dựa trên môi trường nơi chúng được tạo ra, giúp code linh hoạt và mạnh mẽ hơn.
Thử thách
DễTạo một chương trình minh họa closure bằng cách xây dựng hệ thống tạo tin nhắn được cá nhân hóa. Chương trình của bạn sẽ tạo các hàm “ghi nhớ” thông tin cụ thể và dùng thông tin đó để tạo tin nhắn tùy chỉnh ngay cả sau khi ngữ cảnh ban đầu kết thúc.
- Đọc một chuỗi đầu vào đại diện cho tên một người
- Đọc một chuỗi đầu vào đại diện cho kiểu lời chào (
"formal","casual"hoặc"friendly") - Đọc một chuỗi đầu vào đại diện cho tên công ty
- Tạo một hàm có tên
createMessageGenerator, nhận tên và kiểu lời chào làm tham số - Hàm
createMessageGeneratorsẽ trả về một hàm khác (closure), hàm này: - Nhận tên công ty làm tham số
- Dùng tên và kiểu lời chào từ phạm vi của hàm bên ngoài
- Trả về tin nhắn đã định dạng dựa trên kiểu lời chào:
- Với
"formal":"Dear [name], we are pleased to welcome you to [company]." - Với
"casual":"Hey [name]! Welcome to [company]!" - Với
"friendly":"Hi [name], so glad you joined [company]!" - Gọi hàm
createMessageGeneratorvới đầu vào tên và kiểu lời chào để nhận hàm closure - Gọi hàm closure được trả về với đầu vào tên công ty để tạo tin nhắn
- Hiển thị kết quả theo đúng định dạng bên dưới
Ví dụ, nếu đầu vào là "Alice", "formal" và "TechCorp", chương trình của bạn sẽ in ra:
Message Generator System
========================
Creating message generator for: Alice
Greeting type: formal
Company: TechCorp
========================
Generated message: Dear Alice, we are pleased to welcome you to TechCorp.
Message generation completed successfullyNếu đầu vào là "Bob", "casual" và "StartupXYZ", chương trình của bạn sẽ in ra:
Message Generator System
========================
Creating message generator for: Bob
Greeting type: casual
Company: StartupXYZ
========================
Generated message: Hey Bob! Welcome to StartupXYZ!
Message generation completed successfullyNếu đầu vào là "Carol", "friendly" và "InnovateLab", chương trình của bạn sẽ in ra:
Message Generator System
========================
Creating message generator for: Carol
Greeting type: friendly
Company: InnovateLab
========================
Generated message: Hi Carol, so glad you joined InnovateLab!
Message generation completed successfullyChương trình của bạn phải minh họa closure bằng cách tạo một hàm trả về một hàm khác. Hàm được trả về (closure) cần truy cập được các biến từ phạm vi của hàm bên ngoài (tên và kiểu lời chào) ngay cả sau khi hàm bên ngoài đã chạy xong. Dùng các câu lệnh điều kiện để xác định định dạng tin nhắn phù hợp dựa trên đầu vào kiểu lời chào.
Tự làm thử
import 'dart:io';
void main() {
// Đọc đầu vào
String? name = stdin.readLineSync();
String? greetingType = stdin.readLineSync();
String? company = stdin.readLineSync();
// Hiển thị tiêu đề hệ thống
print("Message Generator System");
print("========================");
print("Creating message generator for: $name");
print("Greeting type: $greetingType");
print("Company: $company");
print("========================");
// TODO: Viết code bên dưới
// Tạo hàm createMessageGenerator trả về một bao đóng
// Gọi hàm và tạo thông điệp
// In ra kết quả cuối cùng
print("Generated message: \$message");
print("Message generation completed successfully");
}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 Logic và luồng điều khiển
1Thao tác nâng cao với danh sách
Thuộc tính danh sách: đầu và cuốiTrạng thái danh sách: isEmpty và isNotEmpĐảo ngược danh sáchThêm vào danh sách: insertXóa khỏi danh sách: removeWhereTìm trong danh sách: indexOfSắp xếp danh sáchXáo trộn danh sáchÔn tập: trình sắp xếp danh sách4Thao tác nâng cao với Map
Duyệt qua MapKiểm tra khóa và giá trịCác thuộc tính của Map: khóa và giá trịThêm có điều kiện: putIfAbsentXóa mục khỏi MapMap lồng nhauÔn tập: Cập nhật kho hàng7Hàm nâng cao
Hàm ẩn danhTruyền hàm làm đối sốTìm hiểu về bao đóngGiới thiệu về đệ quyHàm đệ quy: Đếm ngượcHàm đệ quy: Giai thừaÔn tập: Bộ xử lý danh sách2Thao tác hàm trên danh sách
Biến đổi bằng 'map'Lọc bằng 'where'Dùng '.toList()'Kiểm tra điều kiện bằng 'any'Điều kiện với 'every'Tìm phần tử bằng 'firstWhere'Ôn tập: lọc dữ liệu5Dự án: Tính tiền giỏ hàng
Thiết lập dự ánThêm mặt hàng vào giỏ8Dự án: Trình phân tích văn bản đơn giản
Tổng quan và thiết lập dự ánĐếm ký tự3Tập hợp
Tập hợp là gì?Tạo tập hợpThêm và xóa phần tử khỏi tập hợpKiểm tra phần tử trong tập hợpChuyển danh sách thành tập hợpPhép hợp của các tập hợpPhép giao của các tập hợpPhép hiệu của các tập hợpÔn tập: danh sách khách mời không trùng lặpTự luyện tập: Trình biên dịch Dart online