0Pricing
Learn Rust Coding · Pelajaran

Makro Prosedural: Derive, Fungsi

Pelajari makro prosedural, termasuk makro `#[derive]` khusus dan makro mirip fungsi, untuk menghasilkan kode yang lebih kompleks.

Makro Prosedural: Derive, Fungsi adalah pelajaran Learn Rust Coding gratis di CoddyKit. Ini adalah pelajaran 2 dari 3. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Learn Rust Coding, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Learn Rust Coding mencakup 3 pelajaran total.

Pengantar Makro Prosedural

Selamat datang di dunia makro prosedural! Berbeda dari makro deklaratif (macro_rules!), makro prosedural bekerja seperti fungsi yang beroperasi langsung pada kode Rust.

Makro ini menerima TokenStream sebagai input, memprosesnya, lalu mengembalikan TokenStream lainnya. Hal ini memungkinkan pembuatan kode yang jauh lebih kompleks.

Jenis-Jenis Makro Prosedural

Rust menyediakan tiga jenis utama makro prosedural:

  • Makro seperti fungsi: Makro ini terlihat dan berperilaku seperti pemanggilan fungsi biasa, misalnya my_macro!(...).
  • Makro derive: Makro ini memungkinkan Anda menerapkan trait secara otomatis pada struct dan enum menggunakan #[derive(MyTrait)].
  • Makro atribut: Makro ini memungkinkan Anda mendefinisikan atribut khusus yang dapat diterapkan pada item, misalnya #[route("/path")].

Crate `proc-macro`

Makro prosedural harus berada di jenis crate khusus miliknya sendiri. Di dalam Cargo.toml, Anda mendeklarasikannya seperti berikut:

Hal ini memberi tahu Cargo bahwa crate tersebut berisi makro yang mengubah kode saat kompilasi.

[package]
name = "my_macros"
version = "0.1.0"
edition = "2021"

[lib]
proc-macro = true

Penjelasan Makro seperti Fungsi

Makro seperti fungsi didefinisikan dengan atribut #[proc_macro] pada sebuah fungsi yang menerima proc_macro::TokenStream dan mengembalikan nilai yang sama.

Makro ini berguna untuk DSL khusus (Bahasa Khusus Domain) atau pengulangan kode yang kompleks yang tidak dapat ditangani oleh macro_rules!.

use proc_macro::TokenStream;

#[proc_macro]
pub fn my_function_macro(input: TokenStream) -> TokenStream {
    // Logic to transform input TokenStream
    // ...
    input // For example, return the input unchanged
}

Contoh Makro seperti Fungsi

Berikut contoh konseptual. Sebuah makro `greet_name!` yang menghasilkan pernyataan pencetakan. Implementasi sebenarnya akan mengurai input TokenStream untuk mengambil nama.

Meskipun definisi makro ini rumit, penggunaannya sederhana dan kuat:

/* In 'my_macros/src/lib.rs' */
use proc_macro::TokenStream;

#[proc_macro]
pub fn greet_name(input: TokenStream) -> TokenStream {
    // Imagine parsing 'input' to get a name like 'World'
    // and generating: println!("Hello, World!");
    "println!(\"Hello, {}!\", \"CoddyKit\");".parse().unwrap()
}

/* In 'my_app/src/main.rs' */
use my_macros::greet_name;

fn main() {
    greet_name!("CoddyKit");
}

Memahami Makro `#[derive]`

Makro derive adalah jenis yang paling umum. Makro ini memungkinkan Anda menerapkan trait secara otomatis pada struct atau enum.

Saat Anda menulis #[derive(Debug)], sebuah makro berjalan saat kompilasi untuk menghasilkan kode yang diperlukan agar tipe Anda menerapkan trait Debug.

Menerapkan `#[derive]` (Konsep)

Makro derive khusus biasanya dibuat menggunakan pustaka seperti syn (untuk mengurai kode Rust menjadi AST) dan quote (untuk menghasilkan kode Rust dari AST).

Anda akan mendefinisikan fungsi yang dianotasi dengan #[proc_macro_derive(MyTrait)], yang menerima TokenStream yang merepresentasikan struct/enum dan mengembalikan implementasi trait yang dihasilkan.

/* In 'my_macros/src/lib.rs' */
use proc_macro::TokenStream;
use syn::{parse_macro_input, DeriveInput};
use quote::quote;

#[proc_macro_derive(MyDebug)] // MyDebug is the trait name
pub fn my_debug_derive(input: TokenStream) -> TokenStream {
    let ast = parse_macro_input!(input as DeriveInput);
    let name = &ast.ident;

    let expanded = quote! {
        impl std::fmt::Debug for #name {
            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
                f.debug_struct(stringify!(#name)).finish()
            }
        }
    };
    expanded.into()
}

Contoh Penggunaan `#[derive(Debug)]`

Mari kita lihat contoh praktis makro derive yang kemungkinan besar pernah Anda gunakan: Debug. Dengan menambahkan #[derive(Debug)] ke struct Point, Rust secara otomatis menerapkan trait Debug, sehingga kita dapat mencetak isinya dengan rapi.

#[derive(Debug)]
struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let p = Point { x: 10, y: 20 };
    println!("My point is: {:?}", p);
}

Makro Atribut: `#[my_attribute]`

Makro atribut mirip dengan makro derive, tetapi dapat diterapkan pada item apa pun (fungsi, struct, modul, dan sebagainya). Makro ini menerima item yang ditempelinya, beserta argumen apa pun di dalam tanda kurung, sebagai input.

Penggunaan umumnya mencakup perutean kerangka kerja web (misalnya, #[get("/users")]) atau penyiapan pengujian (misalnya, #[test]).

/* In 'my_macros/src/lib.rs' */
use proc_macro::TokenStream;

#[proc_macro_attribute]
pub fn log_calls(attr: TokenStream, item: TokenStream) -> TokenStream {
    // Imagine adding println! statements to 'item'
    item
}

/* In 'my_app/src/main.rs' */
use my_macros::log_calls;

#[log_calls("entry_point")]
fn my_function() {
    println!("Inside my_function");
}

fn main() {
    my_function();
}

Kapan Menggunakan Makro yang Mana

  • Makro seperti fungsi: Untuk bahasa mini khusus atau transformasi kompleks pada blok kode arbitrer.
  • Makro derive: Untuk menerapkan trait secara otomatis pada struct dan enum.
  • Makro atribut: Untuk mengubah atau menghasilkan kode di sekitar item tertentu (fungsi, struct) berdasarkan atribut khusus.

Setiap jenis memiliki tujuan unik dalam memperluas sintaks dan kemampuan Rust.

Pemeriksaan Singkat: Jenis Makro

Pernyataan manakah berikut ini tentang makro prosedural yang TRUE?

Ringkasan: Kekuatan Pembuatan Kode

Anda telah menjelajahi dunia tingkat lanjut makro prosedural!

  • Kita telah mempelajari makro seperti fungsi untuk sintaks khusus.
  • Kita memahami bagaimana makro #[derive] mengotomatiskan penerapan trait.
  • Kita telah membahas secara singkat makro atribut untuk pembuatan kode pada tingkat item.

Makro prosedural adalah alat yang sangat berguna untuk mengurangi kode berulang dan memperluas kemampuan Rust, sehingga Anda dapat menulis kode yang menulis kode!

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Makro Prosedural: Derive, Fungsi” gratis?

Ya — teks lengkap “Makro Prosedural: Derive, Fungsi” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Learn Rust Coding, upgrade ke CoddyKit PRO. Kursus Learn Rust Coding mencakup 3 pelajaran total.

Apa yang akan aku pelajari di “Makro Prosedural: Derive, Fungsi”?

Pelajari makro prosedural, termasuk makro `#[derive]` khusus dan makro mirip fungsi, untuk menghasilkan kode yang lebih kompleks. Kamu berlatih Learn Rust Coding dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Learn Rust Coding?

Tidak diperlukan pengalaman sebelumnya. Learn Rust Coding di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 3.

Berapa lama pelajaran “Makro Prosedural: Derive, Fungsi” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Learn Rust Coding ini?

Ya. Setiap pelajaran Learn Rust Coding menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Makro Deklaratif (`macro_rules!`)
  2. Makro Prosedural: Derive, Fungsi
  3. Berinteraksi dengan Rust Tidak Aman
← Kembali ke Learn Rust Coding