Macro
note
ใน Rust มี macro อยู่ 2 ประเภทคือ
macro_fn!()
หรือdeclarative macros
- มีลักษณะและการใช้งานเหมือนกับ function ปกติ แต่ทำงานต่างกันที่macro_fn!()
จะทำการสร้างโค้ดตามที่เรากำหนดไว้ขณะ compile time ในขณะที่ function จะทำงานที่ runtime#[macro_export]
หรือprocedural macros
หรือattribute macros
- จะใช้สำหรับกำหนดคุณลักษณะให้กับระบบการทำงานของ Rust เพื่อสร้างโค้ดตามที่เรากำหนดไว้ขณะ compile time
Declarative Macros
note
ข้อดีเมื่อเปรียบเทียบกับ function
- ไม่มี runtime overhead: code จะถูก inline expand ในขั้นตอน compile-time
- มีความยืดหยุ่นสูง: สามารถสร้างโค้ดที่ซับซ้อนได้โดยใช้ pattern matching
ข้อจำกัด:
- ยากต่อการเขียนและดีบัก: มี Syntax เฉพาะที่ค่อนข้างซับซ้อน ทำให้โค้ดอ่านยากขึ้น:
- ข้อความแสดงข้อผิดพลาดมักจะไม่ชัดเจนเท่ากับฟังก์ชัน
- ไม่สามารถใช้ในทุกบริบท: มีข้อจำกัดในการใช้งานบางสถานการณ์
Procedural Macros
tip
โดยส่วนมากแล้ว เรามักจะได้ใช้ procedural macros
ในการกำหนดคุณลักษณะให้กับ struct,
enum อย่างง่ายๆ (ทางลัด) ผ่าน #[derive]
Example Procedural Macros
#![allow(unused)] fn main() { #[derive(Debug, Clone)] struct User { name: String, age: u8, } // #[derive(Debug, Clone)] จะทำงานเหมือนกับการ manually impl Debug, Clone เองตามด้านล่าง // impl Debug for User { // fn fmt(&self, f: &mut Formatter) -> Result { // write!(f, "User {{ name: {}, age: {} }}", self.name, self.age) // } // } // impl Clone for User { // fn clone(&self) -> Self { // User { // name: self.name.clone(), // age: self.age, // } // } // } }