Misahin Modul ke Dalem File yang Beda
Sejauh ini, semua contoh di bab ini mendefinisikan beberapa modul di dalem satu file. Pas modulnya jadi makin gede, kita mungkin mau mindahin definisi mereka ke file terpisah biar kodenya lebih gampang dinavigasi.
Sebagai contoh, yuk kita mulai dari kode di Listing 7-17 yang punya beberapa modul restoran. Kita bakal ngekstrak modul-modulnya ke dalem file bukannya punya semua modul didefinisikan di file crate root. Di kasus ini, file crate root-nya adalah src/lib.rs, tapi prosedur ini juga berlaku buat binary crates yang mana file crate root-nya adalah src/main.rs.
Pertama kita bakal ngekstrak modul front_of_house ke dalem filenya sendiri.
Hapus kode di dalem kurung kurawal buat modul front_of_house, nyisain cuma
deklarasi mod front_of_house; aja, jadi src/lib.rs isinya cuma kode yang
ditunjukin di Listing 7-21. Perhatiin ya kalau ini nggak bakal bisa di-compile
sampe kita bikin file src/front_of_house.rs di Listing 7-22.
mod front_of_house;
pub use crate::front_of_house::hosting;
pub fn eat_at_restaurant() {
hosting::add_to_waitlist();
}
front_of_house yang body-nya bakal ada di src/front_of_house.rsSelanjutnya, taruh kode yang tadinya ada di dalem kurung kurawal ke file baru
namanya src/front_of_house.rs, kayak yang ditunjukin di Listing 7-22.
Compiler tau buat nyari di file ini karena dia nemu deklarasi modul di
crate root dengan nama front_of_house.
pub mod hosting {
pub fn add_to_waitlist() {}
}
front_of_house di src/front_of_house.rsPerhatiin ya kalau kita cuma perlu load (muat) file pake deklarasi mod
sekali aja di pohon modul kita. Begitu compiler tau filenya adalah bagian
dari project (dan tau di mana letak kode itu di pohon modul gara-gara tempat
kita naruh statement mod), file lain di project kita harus ngerujuk ke kode
di file yang di-load pake path ke tempat di mana dia dideklarasikan, kayak
yang udah dibahas di bagian “Paths (Jalur) buat Ngerujuk Item di Pohon Modul”.
Dengan kata lain, mod itu bukan operasi “include” kayak yang mungkin kita
liat di bahasa pemrograman lainnya.
Selanjutnya, kita bakal ngekstrak modul hosting ke dalem filenya sendiri.
Prosesnya agak beda karena hosting adalah anak modul dari front_of_house,
bukan dari modul root. Kita bakal naruh file buat hosting di direktori
baru yang namanya ngikutin leluhurnya di pohon modul, di kasus ini
src/front_of_house.
Buat mulai mindahin hosting, kita ubah src/front_of_house.rs biar isinya
cuma deklarasi dari modul hosting aja:
pub mod hosting;
Terus kita bikin direktori src/front_of_house sama file hosting.rs buat
nampung definisi yang dibikin di modul hosting:
pub fn add_to_waitlist() {}
Kalau kita malah naruh hosting.rs di direktori src, compiler bakal ngarepin
kode hosting.rs ada di modul hosting yang dideklarasikan di crate root,
dan bukan dideklarasikan sebagai anak dari modul front_of_house. Aturan
compiler soal file mana yang harus dicek buat kode modul mana bikin direktori
dan file jadi lebih mirip (match) sama pohon modulnya.
Alternate File Paths (Path File Alternatif)
Sejauh ini kita udah ngebahas path file yang paling idiomatik yang dipake sama
compiler Rust, tapi Rust juga support gaya path file yang lebih lama. Buat
modul namanya front_of_house yang dideklarasikan di crate root, compiler
bakal nyari kode modulnya di:
- src/front_of_house.rs (yang baru aja kita bahas)
- src/front_of_house/mod.rs (gaya lama, tetep di-support path-nya)
Buat modul namanya hosting yang merupakan submodul dari front_of_house,
compiler bakal nyari kode modulnya di:
- src/front_of_house/hosting.rs (yang baru aja kita bahas)
- src/front_of_house/hosting/mod.rs (gaya lama, tetep di-support path-nya)
Kalau kita pake kedua gaya ini buat modul yang sama, kita bakal dapet error compiler. Pake campuran kedua gaya buat modul yang beda di project yang sama itu dibolehin, tapi mungkin bakal ngebingungin orang yang lagi navigasi project kita.
Kekurangan utama dari gaya yang pake file namanya mod.rs adalah project kita bisa berakhir dengan banyak file yang namanya mod.rs, yang bisa ngebingungin pas kita ngebuka mereka semua di editor secara bersamaan.
Kita udah mindahin kode tiap modul ke file yang terpisah, dan pohon modulnya
tetep sama. Pemanggilan fungsi di eat_at_restaurant bakal jalan tanpa
modifikasi apa pun, walaupun definisinya sekarang tinggal di file yang beda.
Teknik ini ngebolehin kita mindahin modul ke file baru seiring ukurannya makin
gede.
Perhatiin ya kalau statement pub use crate::front_of_house::hosting di
src/lib.rs juga nggak berubah, dan use juga nggak punya pengaruh apa pun
ke file mana yang di-compile sebagai bagian dari crate-nya. Keyword mod
mendeklarasikan modul, dan Rust nyari di file dengan nama yang sama kayak
modulnya buat nyari kode yang masuk ke modul itu.
Ringkasan
Rust ngebolehin kita misahin sebuah package jadi beberapa crates dan sebuah
crate jadi beberapa modul biar kita bisa ngerujuk ke item yang didefinisikan
di satu modul dari modul lain. Kita bisa lakuin ini dengan nentuin absolute
atau relative paths. Path-path ini bisa dibawa ke dalem scope pake statement
use biar kita bisa pake path yang lebih pendek buat banyak pemakaian item itu
di scope tersebut. Kode modul itu private secara default, tapi kita bisa
bikin definisinya jadi public dengan nambahin keyword pub.
Di bab berikutnya, kita bakal liat beberapa struktur data koleksi (collection) di standard library yang bisa kita pake di dalem kode kita yang udah terorganisir dengan rapi.