Rust Macro - "Procedural Macro", một công cụ mạnh mẽ
Bên cạnh các "declarative macro" (xem ở đây, ở đây và ở đây), Rust còn cung cấp một công cụ rất mạnh đó là các "procedural macro". Nếu "declarative macro" là máy bay tiêm kích thế hệ 3 thì chắc "procedural macro" phải là thế hệ thứ 5.
Các "procedural macro" có ba loại con: "derive macro", "attribute macro" và "function macro". Mỗi loại sẽ phù hợp hay có thể nói là tốt nhất cho một số bài toán cụ thể. Trước khi bắt đầu, tôi cũng cần nhấn mạnh rằng, việc xây dựng các "procedural macro" sẽ đòi hỏi chúng ta phải tự phân tích cú pháp các dòng token ("token stream") đầu vào, tất nhiên cũng có sẵn một vài gói thư viện hỗ trợ rất tốt cho việc này và giảm tương đối công sức cho lập trình viên, nhưng với mục đích để học và thực sự hiểu "procedural macro" thì chúng ta không nên vội vàng sử dụng chúng. Cái giá của sự tiện nghi luôn là che dấu đi rất nhiều chi tiết kỹ thuật và hiển nhiên là điều đó không tốt cho việc học.
Chúng ta sẽ bắt đầu với "derive macro", các lệnh bó sinh mã dạng này thường được dùng để triển khai bổ sung thêm các thuộc tính hành vi ("trait") cho các struct
hoặc enum
. Một ví dụ hay thấy nhất khi lập trình Rust là khai báo #[derive(Debug)]
để triển khai thuộc tính hành vi Debug
sẵn có trong thư viện std
của Rust trên các cấu trúc do lập trình viên tự định nghĩa, nhờ đó chúng ta có thể dùng lệnh in ra màn hình một thực thể chứa các giá trị hiện tại của cấu trúc khi chương trình hoạt động.
Để triển khai một "derive macro", chúng ta sẽ phải khai báo trong Cargo.toml của gói thư viện với mẫu như sau: (proc-macro
là bắt buộc, hai tham số còn lại điều chỉnh theo mã nguồn cụ thể)
[lib]
proc-macro = true
path = "./src/lib.rs"
name = "mylib_macros"
và trong lib.rs bắt buộc phải theo mẫu: (với TypeName và type_name_derive do lập trình viên tự đặt)
use proc_macro::{TokenStream, TokenTree};
#[proc_macro_derive(TypeName)]
pub fn type_name_derive(input: TokenStream) -> TokenStream {
...
}
Để tiếp tục tìm hiểu và thực hành việc phát triển các "derive macro", hãy cùng xem video "#0044 - Rust Macro - 04 Procedural Macro - Phần 01" trên kênh Youtube RustDEV Vietnam.
Cảm ơn các bạn.
All rights reserved