Menu
CoddyTech

Mệnh đề where

Thuộc phần Lập trình hướng đối tượng trong hành trình Rust của Coddy. Bài học 42 trên 61.

Khi thêm nhiều trait bound, chữ ký hàm có thể trở nên khó đọc. Hãy xem xét một hàm có nhiều tham số tổng quát, mỗi tham số cần nhiều trait:

fn complex_operation<T: Display + Clone, U: Debug + Summary>(first: T, second: U) {
    // ...
}

Cách này hiệu quả, nhưng phần khai báo hàm đang trở nên rườm rà. Mệnh đề where là một lựa chọn gọn gàng hơn, giúp chuyển các ràng buộc trait xuống sau danh sách tham số:

fn complex_operation<T, U>(first: T, second: U)
where
    T: Display + Clone,
    U: Debug + Summary,
{
    // ...
}

Cả hai phiên bản có chức năng giống hệt nhau: mệnh đề where chỉ giúp câu lệnh dễ đọc hơn. Các yêu cầu của từng kiểu dữ liệu được viết trên một dòng riêng, giúp bạn dễ xem từng tham số tổng quát cần gì.

Mệnh đề where đặc biệt hữu ích khi các ràng buộc phức tạp hoặc khi bạn có nhiều tham số tổng quát. Mệnh đề này giúp bạn dễ dàng thấy tên hàm và các tham số, còn các ràng buộc được liệt kê riêng bên dưới. Đây là phong cách được ưu tiên trong hầu hết các codebase Rust khi các ràng buộc phức tạp hơn T: Trait đơn giản.

challenge icon

Thử thách

Dễ

Hãy xây dựng một hệ thống xử lý dữ liệu dùng mệnh đề where để giúp các ràng buộc trait phức tạp dễ đọc hơn! Bạn sẽ tạo một hàm tổng quát có nhiều tham số kiểu, mỗi tham số yêu cầu các trait khác nhau, rồi sắp xếp các ràng buộc rõ ràng bằng cú pháp where.

Bạn sẽ chia code thành hai tệp:

  • processor.rs: Định nghĩa hai trait công khai và một hàm tổng quát dùng cả hai:
    • Summarize: một trait có phương thức summary, nhận &self và trả về String
    • Validate: một trait có phương thức validate, nhận &self và trả về bool
    Sau đó, tạo một hàm tổng quát công khai tên là process_items, nhận hai tham số thuộc các kiểu tổng quát khác nhau. Dùng mệnh đề where để quy định rằng kiểu thứ nhất phải triển khai cả Clone và Summarize, còn kiểu thứ hai phải triển khai Validate. Hàm cần in ra phần tóm tắt của phần tử thứ nhất, rồi in ra phần tử thứ hai có hợp lệ hay không.
  • main.rs: Tạo hai cấu trúc công khai triển khai các trait cần thiết:
    • Article: có trường title công khai (String). Triển khai Summarize để trả về Article: {title}, và dẫn xuất Clone.
    • Form: có trường filled công khai (bool). Triển khai Validate để trả về giá trị của filled.
    Dùng các đầu vào đã cho để tạo một Article và một Form, rồi gọi process_items với cả hai.

Mệnh đề where giúp chữ ký hàm gọn gàng hơn nhiều so với việc nhồi tất cả ràng buộc vào dấu ngoặc nhọn. Yêu cầu của từng kiểu nằm trên một dòng riêng, giúp bạn dễ thấy mỗi tham số tổng quát cần gì.

Đầu ra cần hiển thị phần tóm tắt, sau đó là kết quả xác thực:

Article: {title}
Valid: {true/false}

Ví dụ, với đầu vào Rust Tips và true:

Article: Rust Tips
Valid: true

Và với đầu vào Breaking News và false:

Article: Breaking News
Valid: false

Bạn sẽ nhận hai đầu vào: tiêu đề bài viết và thông tin biểu mẫu đã được điền hay chưa (phân tích thành bool).

Tự làm thử

mod processor;

use processor::{Summarize, Validate, process_items};
use std::io;

// TODO: Định nghĩa một struct public Article với trường title public (String)
// Thêm derive Clone cho Article

// TODO: Triển khai Summarize cho Article
// Phương thức summary cần trả về "Article: {title}"

// TODO: Định nghĩa một struct public Form với trường filled public (bool)

// TODO: Triển khai Validate cho Form
// Phương thức validate cần trả về giá trị của filled

fn main() {
    let mut title = String::new();
    io::stdin().read_line(&mut title).expect("Failed to read line");
    let title = title.trim().to_string();

    let mut filled_input = String::new();
    io::stdin().read_line(&mut filled_input).expect("Failed to read line");
    let filled: bool = filled_input.trim().parse().expect("Failed to parse bool");

    // TODO: Tạo một Article với title đã cho
    
    // TODO: Tạo một Form với giá trị filled đã cho
    
    // TODO: Gọi process_items với article và form
}
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 Rust online