Menu
CoddyTech

Records (Dart 3)

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

Dart 3 giới thiệu records, một cách gọn nhẹ để nhóm nhiều giá trị lại với nhau mà không cần tạo cả một lớp. Records không thể thay đổi, có sẵn phép so sánh bằng và rất phù hợp để trả về nhiều giá trị từ một hàm hoặc tạm thời nhóm các dữ liệu liên quan.

Tạo một bản ghi bằng cách đặt các giá trị trong dấu ngoặc đơn:

void main() {
  // Một bản ghi (record) đơn giản với hai giá trị (value)
  var point = (10, 20);
  print(point.$1);  // 10: truy cập phần tử (element) đầu tiên
  print(point.$2);  // 20: truy cập phần tử thứ hai
  
  // Các bản ghi có trường được đặt tên
  var person = (name: 'Alice', age: 30);
  print(person.name);  // Alice
  print(person.age);   // 30
}

Truy cập các trường theo vị trí bằng $1, $2, v.v., còn các trường có tên thì dùng trực tiếp tên của chúng. Bạn có thể kết hợp cả hai kiểu trong một bản ghi.

Bản ghi rất hữu ích khi hàm trả về nhiều giá trị, bạn không cần tạo lớp chỉ để trả về hai phần dữ liệu:

(int, int) divideWithRemainder(int a, int b) {
  return (a ~/ b, a % b);
}

(String name, int age) getUser() {
  return ('Bob', 25);
}

void main() {
  var (quotient, remainder) = divideWithRemainder(17, 5);
  print('$quotient remainder $remainder');  // 3 remainder 2
  
  var (name, age) = getUser();
  print('$name is $age');  // Bob là 25
}

Các record tự động hỗ trợ phép so sánh bằng dựa trên giá trị, giúp bạn so sánh thuận tiện mà không cần tự triển khai ==. Dùng record khi bạn cần nhóm dữ liệu đơn giản, bất biến; dùng lớp khi bạn cần phương thức, khả năng thay đổi hoặc hành vi phức tạp hơn.

challenge icon

Thử thách

Dễ

Hãy cùng xây dựng một hệ tọa độ bằng các record! Bạn sẽ tạo các hàm hoạt động với điểm 2D được biểu diễn dưới dạng record, qua đó thấy được record giúp trả về và làm việc với nhiều giá trị liên quan dễ dàng như thế nào mà không cần tạo lớp đầy đủ.

Bạn sẽ sắp xếp code vào hai tệp:

  • geometry.dart: Tạo các hàm dùng record để làm việc với dữ liệu tọa độ:
    • Một hàm createPoint(int x, int y) trả về một record có các trường được đặt tên là x và y. Kiểu trả về cần là ({int x, int y})
    • Một hàm midpoint(({int x, int y}) p1, ({int x, int y}) p2) tính và trả về trung điểm giữa hai điểm dưới dạng record có các trường được đặt tên. Dùng phép chia nguyên (~/) để tính
    • Một hàm distance(({int x, int y}) p1, ({int x, int y}) p2) trả về một record có các trường theo vị trí: khoảng cách ngang (độ chênh lệch theo x) và khoảng cách dọc (độ chênh lệch theo y). Kiểu trả về cần là (int, int). Tính bằng p2.x - p1.x và p2.y - p1.y
  • main.dart: Nhập tệp hình học của bạn và minh họa cách dùng record:
    • Tạo hai điểm bằng createPoint: điểm A tại (2, 4) và điểm B tại (10, 8)
    • In Point A: ([x], [y]) bằng các trường được đặt tên
    • In Point B: ([x], [y]) bằng các trường được đặt tên
    • Tính trung điểm và in Midpoint: ([x], [y])
    • Tính khoảng cách và dùng phép phân rã để lấy các giá trị vào hai biến dx và dy, sau đó in Distance: dx=[dx], dy=[dy]

Hãy chú ý cách record giúp bạn trả về nhiều giá trị một cách gọn gàng: dùng trường được đặt tên để rõ nghĩa khi cần, còn trường theo vị trí khi ngữ cảnh đã rõ!

Đầu ra dự kiến:

Point A: (2, 4)
Point B: (10, 8)
Midpoint: (6, 6)
Distance: dx=8, dy=4

Tự làm thử

import 'geometry.dart';

void main() {
  // TODO: Tạo điểm A tại (2, 4) bằng createPoint
  
  // TODO: Tạo điểm B tại (10, 8) bằng createPoint
  
  // TODO: In ra điểm A bằng các trường có tên: Point A: ([x], [y])
  
  // TODO: In ra điểm B bằng các trường có tên: Point B: ([x], [y])
  
  // TODO: Tính trung điểm rồi in ra: Midpoint: ([x], [y])
  
  // TODO: Tính khoảng cách và dùng phép phân rã để lấy dx và dy
  // Sau đó in ra: Distance: dx=[dx], dy=[dy]
}
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