Menu
CoddyTech

Mẫu và đối sánh (3.0)

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 87 trên 110.

Dart 3 giới thiệu so khớp mẫu, một cách mạnh mẽ để phân rã và kiểm tra dữ liệu trong một biểu thức. Mẫu cho phép bạn trích xuất giá trị từ các đối tượng, kiểm tra cấu trúc của chúng và gán giá trị cho các biến cùng lúc.

Bạn đã thấy cách phân rã cơ bản với record. Mẫu giúp mở rộng cách này để làm việc với đối tượng, danh sách và map:

void main() {
  // Mẫu danh sách
  var numbers = [1, 2, 3];
  var [a, b, c] = numbers;
  print('$a, $b, $c');  // 1, 2, 3
  
  // Mẫu ánh xạ
  var user = {'name': 'Alice', 'age': 30};
  var {'name': name, 'age': age} = user;
  print('$name is $age');  // Alice is 30
}

Pattern trở nên đặc biệt mạnh mẽ trong các biểu thức switch. Bạn có thể đồng thời khớp theo kiểu, giá trị và cấu trúc:

String describe(Object obj) {
  return switch (obj) {
    int n when n < 0 => 'Negative number',
    int n => 'Positive number: $n',
    String s => 'String of length ${s.length}',
    [int first, ...] => 'List starting with $first',
    _ => 'Something else',
  };
}

void main() {
  print(describe(-5));        // Số âm
  print(describe(42));        // Số dương: 42
  print(describe([1, 2, 3])); // Danh sách bắt đầu bằng 1
}

Mệnh đề when bổ sung điều kiện cho các mẫu, còn ... khớp với các phần tử còn lại trong danh sách. Dấu gạch dưới _ đóng vai trò là ký tự đại diện, khớp với mọi thứ. Khi kết hợp với các lớp sealed, mẫu cho phép xử lý đầy đủ và an toàn về kiểu đối với các cấu trúc dữ liệu phức tạp.

challenge icon

Thử thách

Dễ

Hãy xây dựng một bộ phân loại dữ liệu sử dụng tính năng khớp mẫu (pattern matching) để phân tích và phân loại nhiều kiểu đầu vào! Bạn sẽ tạo một hệ thống có thể nhận diện và mô tả nhiều cấu trúc dữ liệu bằng các tính năng khớp mẫu mạnh mẽ của Dart 3.

Bạn sẽ sắp xếp code thành hai tệp:

  • classifier.dart: Tạo một hàm có tên classify, nhận tham số Object và trả về phần mô tả kiểu String. Dùng biểu thức switch với tính năng khớp mẫu để xử lý các trường hợp sau:
    • Danh sách rỗng [] sẽ trả về Empty list
    • Danh sách có đúng một phần tử số nguyên sẽ trả về Single item: [value]
    • Danh sách có đúng hai phần tử sẽ trả về Pair: [first] and [second]
    • Danh sách bắt đầu bằng một số nguyên, theo sau là các phần tử khác, sẽ trả về List starting with [first], length: [total length] (dùng mẫu phần còn lại ...)
    • Từ điển chứa cả hai khóa 'name' và 'age' sẽ trả về [name] is [age] years old (dùng phép phân rã bằng mẫu từ điển)
    • Số nguyên âm (dùng mệnh đề when) sẽ trả về Negative: [value]
    • Số nguyên bằng không sẽ trả về Zero
    • Mọi số nguyên khác sẽ trả về Positive: [value]
    • Mọi giá trị khác sẽ trả về Unknown type
  • main.dart: Nhập bộ phân loại và minh họa tính năng khớp mẫu với nhiều đầu vào. In ra kết quả phân loại từng giá trị sau:
    • Danh sách rỗng []
    • Danh sách có một phần tử: [42]
    • Danh sách có hai phần tử: ['hello', 'world']
    • Danh sách dài hơn: [1, 2, 3, 4, 5]
    • Một từ điển: {'name': 'Alice', 'age': 25}
    • Số nguyên -10
    • Số nguyên 0
    • Số nguyên 99

Thử thách này kết hợp mẫu danh sách, mẫu từ điển, mệnh đề when để kiểm tra điều kiện và mẫu phần còn lại (...), tất cả đều là những tính năng khớp mẫu chính trong bài học!

Đầu ra dự kiến:

Empty list
Single item: 42
Pair: hello and world
List starting with 1, length: 5
Alice is 25 years old
Negative: -10
Zero
Positive: 99

Tự làm thử

import 'classifier.dart';

void main() {
  // TODO: Dùng hàm (function) classify để phân loại từng giá trị
  // và in ra kết quả
  
  // Thử với một danh sách rỗng
  print(classify([]));
  
  // TODO: Thử với danh sách có một phần tử: [42]
  
  // TODO: Thử với danh sách có hai phần tử: ['hello', 'world']
  
  // TODO: Thử với danh sách dài hơn: [1, 2, 3, 4, 5]
  
  // TODO: Thử với một map: {'name': 'Alice', 'age': 25}
  
  // TODO: Thử với số nguyên -10
  
  // TODO: Thử với số nguyên 0
  
  // TODO: Thử với số nguyên 99
}
quiz iconTự kiểm tra

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

Tự luyện tập: Trình biên dịch Dart online