Doc comment /// dari Chapter sebelumnya menjelaskan item satu per satu: satu fungsi, satu struct, satu field. Pendekatan itu melahirkan dokumentasi yang rapi per item, tetapi tetap menyisakan lubang: pembaca yang baru membuka crate kita tidak menemukan satu kalimat pun yang menjelaskan apa isi crate secara keseluruhan, dari mana memulai, dan konvensi apa yang dipakai seluruh API. Lubang yang sama muncul pada modul besar — modul berisi belasan fungsi publik tanpa pengantar. Rust mengisi lubang ini dengan inner doc comment //!, komentar yang mendeskripsikan wadahnya, bukan item di bawahnya. Chapter ini mempelajari penempatan //! pada level crate dan level modul, cara rustdoc memperlakukannya, serta error yang muncul bila //! dipasang di posisi yang salah.
Aturan: //! Mendeskripsikan Item yang Mengandungnya #
Perbedaan arah adalah inti aturannya: /// diproses sebagai dokumentasi untuk item berikutnya (dokumentasi dari luar item), sedangkan //! diproses sebagai dokumentasi untuk item yang sedang mengandungnya (dokumentasi dari dalam). Karena itu //! hanya bermakna di posisi isi — bagian dalam dari suatu wadah. Wadah yang sah untuk //! ada dua: crate root (src/lib.rs atau src/main.rs), tempat //! menjadi ringkasan seluruh crate, dan blok modul, tempat //! menjadi pengantar modul tersebut.
Konsekuensi penempatannya tegas: //! harus ditulis sebelum item-item pertama dari wadahnya. Di src/lib.rs, baris-baris //! berdiri di paling atas file, mendahului pub mod, pub fn, dan use. Di dalam modul file terpisah atau blok mod { }, //! juga menempati baris-baris pertama isinya. Rust menyebut error E0753 untuk setiap pelanggaran posisi ini, dan pesan error-nya — seperti akan kita lihat — bahkan menawarkan dua kandidat perbaikan.
Mekanisme: Dokumentasi Wadah oleh rustdoc #
Compiler menyimpan //! sebagai atribut doc yang melekat pada wadah, bukan pada item di dalamnya. Saat rustdoc membangun dokumentasi, teks //! di crate root menjadi halaman depan dokumentasi crate — halaman pertama yang dilihat pembaca, setara halaman utama crate populer di docs.rs. Teks //! di dalam modul menjadi bagian pengantar pada halaman modul tersebut, tampil di atas daftar item yang dimuatnya. Sama seperti ///, isi //! berformat Markdown dan setiap blok kode berpagar di dalamnya ikut menjadi doc test — meski praktik umumnya ringkasan crate hanya memuat contoh kecil pemakaian crate, bukan kumpulan test panjang.
Contoh: Ringkasan Crate dan Pengantar Modul #
Buat proyek library dengan cargo new kasir --lib. Kita akan memakai struktur modul file terpisah agar kedua posisi //! terlihat sekaligus. Isi src/lib.rs:
//! Modul utama crate `kasir` untuk penghitungan transaksi warung kopi.
//!
//! Crate ini menyediakan fungsi penghitungan kembalian dan pembulatan
//! harga. Semua nilai uang memakai tipe `u64` dalam satuan rupiah.
pub mod struk;
/// Membulatkan harga ke ribuan terdekat ke bawah.
///
/// # Examples
///
/// ```
/// let dibulatkan = kasir::bulatkan_ribuan(18_750);
/// assert_eq!(dibulatkan, 18_000);
/// ```
pub fn bulatkan_ribuan(harga: u64) -> u64 {
harga / 1_000 * 1_000
}Lalu buat file src/struk/mod.rs:
//! Perhitungan struk belanja pelanggan.
//!
//! Modul ini menghitung total tagihan dan kembalian uang tunai.
/// Menghitung kembalian dari pembayaran tunai.
///
/// # Examples
///
/// ```
/// let kembalian = kasir::struk::hitung_kembalian(50_000, 43_000);
/// assert_eq!(kembalian, 7_000);
/// ```
pub fn hitung_kembalian(dibayar: u64, tagihan: u64) -> u64 {
dibayar - tagihan
}Jalankan test untuk membuktikan kedua doc comment hidup:
cargo testOutput yang Dihasilkan:
Compiling kasir v0.1.0 (/tmp/w5b-dokcrate)
Finished `test` profile [unoptimized + debuginfo] target(s) in 0.14s
Running unittests src/lib.rs (target/debug/deps/kasir-602213a697e0d50c)
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Doc-tests kasir
running 2 tests
test src/struk/mod.rs - struk::hitung_kembalian (line 9) ... ok
test src/lib.rs - bulatkan_ribuan (line 12) ... ok
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
all doctests ran in 0.15s; merged doctests compilation took 0.15sDua doc test lulus, satu dari setiap file. Mari kita bedah penempatan //! di atas:
- Baris 1-4
src/lib.rs(//! Modul utama crate kasir ...): empat baris//!berdiri di posisi paling atas crate root, mendahului semua item. Teks ini menjadi halaman depan dokumentasi crate — paragraf pertamanya tampil sebagai ringkasan crate di daftar pencarian. - Baris 6 (
pub mod struk;): deklarasi modul. Posisinya setelah blok//!adalah syarat —//!hanya boleh muncul sebelum item, jadi seluruh ringkasan crate harus selesai sebelum deklarasi modul pertama. - Baris 8-15 (
/// Membulatkan harga ...): doc comment///biasa untuk fungsibulatkan_ribuan. Campuran//!(wadah) dan///(item) dalam satu file adalah pola standar crate root: ringkasan besar di atas, dokumentasi per item di bawah. - Baris 1-3
src/struk/mod.rs(//! Perhitungan struk belanja ...)://!di baris-baris pertama isi modulstruk. Karena modul ini berupa file terpisah, isi modul dimulai dari baris pertama file —//!langsung sah berdiri di sana dan menjadi pengantar halaman dokumentasi modulstruk. - Baris 5-12
src/struk/mod.rs(/// Menghitung kembalian ...): fungsi di dalam modul tetap memakai///—//!tidak pernah dipakai untuk fungsi, karena fungsi bukan wadah item lain. - Baris laporan
test src/struk/mod.rs - struk::hitung_kembalian (line 9): nama doc test memuat path lengkap modulnya (struk::hitung_kembalian) dan baris pagar contohnya — bukti rustdoc menjelajah modul file terpisah tanpa konfigurasi tambahan.
Penempatan yang Salah dan Pesan E0753 #
Compiler menjaga posisi //! dengan error E0753. Kasus klasiknya: menaruh //! di tengah atau di akhir file, setelah item lain selesai:
fn main() {
println!("hai");
}
//! Ringkasan crate di posisi yang salah.
Pesan error compiler:
error[E0753]: expected outer doc comment
--> src/main.rs:4:1
|
4 | //! Ringkasan crate di posisi yang salah.
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: inner doc comments like this (starting with `//!` or `/*!`) can only appear before items
help: you might have meant to write a regular comment
|
4 - //! Ringkasan crate di posisi yang salah.
4 + // Ringkasan crate di posisi yang salah.
|
error: expected item after doc comment
--> src/main.rs:4:1
|
4 | //! Ringkasan crate di posisi yang salah.
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this doc comment doesn't document anything
error: could not compile `kasir` (bin "kasir") due to 2 previous errorsDua error terbit dari satu kesalahan. E0753 menyatakan aturannya: inner doc comment hanya boleh muncul sebelum item; setelah fungsi main selesai, posisi kita bukan lagi “sebelum item” melainkan “setelah item”. Error kedua menegaskan tidak ada item yang mengandung komentar tersebut. Saran perbaikannya jujur dan berguna: bila maksud kita hanya mencatat sesuatu di akhir file, ubah //! menjadi komentar biasa //. Bila maksud kita memang menulis ringkasan crate, pindahkan blok //! ke baris-baris paling atas file.
Ringkasan #
//! mendeskripsikan wadah yang mengandungnya: crate root di src/lib.rs dan isi modul di file modul terpisah atau blok mod. Kedua tempat itu memerlukan //! di baris-baris pertama sebelum item apa pun, dikerjakan rustdoc menjadi halaman depan crate dan pengantar modul, dan blok contoh di dalamnya tetap menjadi doc test. Pelanggaran posisi memicu E0753 lengkap dengan saran mengubah ke // atau memindahkan blok ke atas. Dengan /// dan //!, seluruh teks dokumentasi kini tersimpan di source code; Chapter berikutnya mengubah teks tersebut menjadi halaman HTML yang bisa ditelusuri lewat cargo doc.