0Pricing
Learn Rust Coding · บทเรียน

มาโครแบบประกาศ (`macro_rules!`)

เรียนรู้การเขียนมาโครแบบประกาศเพื่อแยกรูปแบบโค้ดที่ซ้ำกันเป็นนามธรรมและสร้างโค้ดขณะคอมไพล์

มาโครแบบประกาศ (`macro_rules!`) เป็นบทเรียน Learn Rust Coding ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 3 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Learn Rust Coding และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Learn Rust Coding มีบทเรียนทั้งหมด 3 บทเรียน

มาโคร Rust คืออะไร

มาโครเป็นวิธีเขียนโค้ดที่ใช้เขียนโค้ดอีกที! มาโครคล้ายฟังก์ชัน แต่ทำงานกับต้นไม้ไวยากรณ์ (โครงสร้างของโค้ด) แทนค่า

  • ช่วยลดความซ้ำซ้อนของโค้ด
  • ช่วยให้ใช้ภาษาสำหรับโดเมนเฉพาะ (DSL) ภายใน Rust ได้
  • ทำงานขณะคอมไพล์ โดยขยายเป็นโค้ด Rust ปกติก่อนการคอมไพล์

ไวยากรณ์ของมาโครแบบประกาศ

มาโครแบบประกาศของ Rust ใช้คีย์เวิร์ด macro_rules! โดยกำหนดชุดกฎที่จับคู่กับรูปแบบเฉพาะของโค้ด Rust

ลองนึกภาพว่าเป็นการจับคู่รูปแบบสำหรับส่วนย่อยของโค้ด เมื่อคอมไพเลอร์พบการเรียกใช้มาโคร ก็จะพยายามจับคู่อินพุตกับกฎข้อใดข้อหนึ่งที่คุณกำหนดไว้

`macro_rules!` แรกของคุณ

มาสร้างมาโครอย่างง่ายที่พิมพ์คำทักทายกัน สังเกตคีย์เวิร์ด macro_rules! และไวยากรณ์ () => {} ซึ่งกำหนดกฎที่ไม่มีรูปแบบอินพุต

ลองเรียกใช้ตัวอย่างนี้:

macro_rules! greet {
    () => {
        println!("Hello from a macro!");
    };
}

fn main() {
    greet!(); // Call our macro!
}

รับอินพุตด้วยตัวระบุรูปแบบ

มาโครสามารถรับอินพุตโดยใช้ "ตัวระบุรูปแบบ" ซึ่งจะบอกมาโครว่าควรคาดหวังและจับไวยากรณ์ Rust ประเภทใด

  • $expr: นิพจน์ (เช่น 1 + 2, "hello")
  • $ident: ตัวระบุ (เช่น ชื่อตัวแปร ชื่อฟังก์ชัน)
  • $ty: ชนิดข้อมูล (เช่น i32, String)
  • $block: บล็อกโค้ด (เช่น { ... })
  • ...และยังมีอีกมากมาย!

มาโครที่รับอาร์กิวเมนต์

ต่อไปนี้คือมาโครที่รับนิพจน์ ($e:expr) และพิมพ์ค่าของนิพจน์นั้น ส่วน :expr คือตัวระบุรูปแบบ

จากนั้น $e ที่จับมาได้จะพร้อมใช้งานในเนื้อหาของมาโคร มาโคร stringify! จะแปลงนิพจน์ให้เป็นตัวแทนในรูปสตริง

macro_rules! debug_print {
    ($e:expr) => {
        println!("Debug: {} = {:?}", stringify!($e), $e);
    };
}

fn main() {
    let x = 10;
    debug_print!(x + 5);
    debug_print!("Rust macros are fun");
}

จัดการอินพุตหลายรายการ

หากต้องการให้แมโครรับอาร์กิวเมนต์หลายรายการที่มีชนิดเดียวกัน คุณสามารถใช้ตัวดำเนินการทำซ้ำได้ดังนี้: $()*

  • $(): เนื้อหาภายในคือรูปแบบที่จะทำซ้ำ
  • *: ทำซ้ำตั้งแต่ศูนย์ครั้งขึ้นไป
  • +: ทำซ้ำตั้งแต่หนึ่งครั้งขึ้นไป
  • คุณยังสามารถระบุตัวคั่นได้ เช่น $(...),* สำหรับรายการที่คั่นด้วยจุลภาค

แมโครที่มีอาร์กิวเมนต์ทำซ้ำ

มาสร้างแมโครที่รับนิพจน์หลายรายการซึ่งคั่นด้วยจุลภาค และพิมพ์แต่ละรายการแยกกัน ความสามารถนี้มีประโยชน์อย่างมากสำหรับการสร้างโครงสร้างที่มีลักษณะเหมือนรายการ

macro_rules! print_all {
    ( $( $x:expr ),* ) => {
        $( // This $(...)* repeats the `println!` call
            println!("Item: {:?}", $x);
        )*
    };
}

fn main() {
    print_all!(1, "hello", true, 3.14);
    print_all!("Just one item");
}

ทำความเข้าใจความเป็นระเบียบของแมโคร

แมโครของ Rust มี "ความเป็นระเบียบ" ซึ่งหมายความว่า ตัวแปรที่กำหนดภายในแมโครจะไม่ชนกับตัวแปรภายนอกโดยไม่ได้ตั้งใจ แม้ว่าจะใช้ชื่อเดียวกันก็ตาม

คอมไพเลอร์จะเปลี่ยนชื่อสิ่งต่าง ๆ ภายในระหว่างการขยายแมโคร เพื่อป้องกันผลข้างเคียงที่ไม่ต้องการ ทำให้แมโครปลอดภัยและคาดเดาพฤติกรรมได้มากขึ้น

วิธีแก้ไขข้อบกพร่องของแมโคร

บางครั้งแมโครอาจไม่ขยายผลลัพธ์ตามที่คุณคาดไว้ Rust มีวิธีดูโค้ดที่ขยายแล้วดังนี้:

  • เรียกใช้ cargo expand (ต้องติดตั้งเครื่องมือ cargo-expand ก่อน)
  • ใช้ rustc --pretty expanded กับไฟล์ต้นฉบับโดยตรง

วิธีนี้จะแสดงโค้ด Rust ดิบที่แมโครของคุณสร้างขึ้น ซึ่งมีประโยชน์อย่างยิ่งต่อการแก้ไขข้อบกพร่องและทำความเข้าใจพฤติกรรมของแมโครที่ซับซ้อน

แบบทดสอบการจับคู่รูปแบบของแมโคร

พิจารณาการกำหนดแมโครต่อไปนี้:

macro_rules! make_tuple {
    ( $x:expr, $y:expr ) => {
        ($x, $y)
    };
}

บรรทัดใดต่อไปนี้จะคอมไพล์และใช้แมโคร make_tuple! ได้สำเร็จ

ทบทวน: แมโครแบบประกาศ

ในบทเรียนนี้ คุณได้เรียนรู้เกี่ยวกับแมโครแบบประกาศโดยใช้ macro_rules!:

  • แมโครเหล่านี้สร้างโค้ดขณะคอมไพล์ และช่วยลดรูปแบบโค้ดที่ต้องเขียนซ้ำ
  • แมโครใช้การจับคู่รูปแบบเพื่อรับอินพุตตามไวยากรณ์
  • ตัวระบุรูปแบบ เช่น $expr และ $ident ใช้ระบุชนิดของไวยากรณ์ที่คาดว่าจะได้รับ
  • ตัวดำเนินการทำซ้ำ เช่น $()* รองรับอาร์กิวเมนต์หลายรายการและตัวคั่นที่ยืดหยุ่น
  • แมโครมีความเป็นระเบียบ จึงป้องกันการขัดแย้งของชื่อโดยไม่ได้ตั้งใจ

แมโครเป็นเครื่องมือที่ทรงพลังสำหรับลดโค้ดส่วนซ้ำซ้อน และสร้าง API ใน Rust ที่ยืดหยุ่นและใช้งานสะดวก

คำถามที่พบบ่อย

บทเรียน “มาโครแบบประกาศ (`macro_rules!`)” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “มาโครแบบประกาศ (`macro_rules!`)” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Learn Rust Coding ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Learn Rust Coding มีบทเรียนทั้งหมด 3 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “มาโครแบบประกาศ (`macro_rules!`)”

เรียนรู้การเขียนมาโครแบบประกาศเพื่อแยกรูปแบบโค้ดที่ซ้ำกันเป็นนามธรรมและสร้างโค้ดขณะคอมไพล์ คุณปฏิบัติ Learn Rust Coding ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Learn Rust Coding หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Learn Rust Coding บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 3 บทเรียน

บทเรียน “มาโครแบบประกาศ (`macro_rules!`)” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Learn Rust Coding นี้ได้ไหม

ได้ บทเรียน Learn Rust Coding ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. มาโครแบบประกาศ (`macro_rules!`)
  2. มาโครเชิงกระบวนการ: Derive, Function
  3. การทำงานร่วมกับ Rust แบบไม่ปลอดภัย
← กลับไปที่ Learn Rust Coding