Menulis crate::front_of_house::hosting::add_to_waitlist() sekali masih terasa wajar; menuliskannya sepuluh kali di dalam satu module membuat jari dan mata sama-sama lelah, dan setiap pengulangan menjadi titik rawan salah ketik. Rust tidak memaksa kita mengulang path panjang: keyword use membawa nama dari tree module turun ke scope lokal, seolah nama tersebut dideklarasikan di module kita sendiri. Chapter ini membahas cara kerja use, cara mengimpor beberapa nama sekaligus dengan kurung kurawal bersarang, cara mengganti nama dengan alias as, serta wujud error E0432 yang muncul ketika path yang kita impor ternyata tidak ada.

use Membawa Nama ke Scope #

Mekanismenya sederhana namun perlu dipahami presisi: use tidak menyalin kode dan tidak menggerakkan item — use hanya menciptakan nama baru di scope saat ini yang menunjuk ke item yang sama di tree module. Nama baru itu mengikuti aturan scope biasa: hidup di dalam module tempat use ditulis, dan berakhir ketika module berakhir. Setelah use crate::front_of_house::hosting; ditulis, kata hosting resmi menjadi nama pendek yang bisa dipakai tanpa mengulang cabang-cabang di depannya. Kita terapkan pada warung kita:

rust
mod front_of_house {
    pub mod hosting {
        pub fn add_to_waitlist() {
            println!("Pelanggan masuk daftar tunggu");
        }
    }
}

use crate::front_of_house::hosting;

fn main() {
    hosting::add_to_waitlist();
    hosting::add_to_waitlist();
}

Output yang Dihasilkan:

text
Pelanggan masuk daftar tunggu
Pelanggan masuk daftar tunggu

Mari kita bedah kode di atas:

  1. Baris 9 (use crate::front_of_house::hosting;): pernyataan use membawa module hosting ke scope crate root. Sejak baris ini, nama hosting sah dipakai di seluruh scope yang sama, termasuk di dalam main.
  2. Baris 12 dan Baris 13 (hosting::add_to_waitlist();): pemanggilan kini cukup menulis nama yang dibawa use beserta item di dalamnya. Path panjang crate::front_of_house::hosting::add_to_waitlist() tidak perlu lagi ditulis.

Satu keputusan gaya yang tampak di contoh: kita mengimpor module hosting, bukan langsung fungsinya. Penulisan hosting::add_to_waitlist() pada pemanggilan menjaga konteks — pembaca tahu fungsi itu urusan pendaftaran pelanggan di area hosting. Konvensi umum komunitas pun begitu: impor module hingga tingkat yang membuat pemanggilan terbaca jelas; impor fungsi atau item langsung boleh dilakukan, namun paling sering dipakai saat nama modulnya kurang menambah makna — misalnya use std::env::var; yang lazim untuk pembacaan environment variable.

Lokasi penulisan use juga mengikuti aturan scope biasa. Pernyataan di tingkat berkas — seperti contoh kita — berlaku untuk seluruh item pada module itu. Pernyataan di dalam sebuah fungsi hanya berlaku sampai kurung kurawal fungsi tersebut, dan pola ini berguna ketika satu fungsi membutuhkan nama yang tidak dipakai saudaranya. Kompilator bahkan mengingatkan lewat warning unused import ketika nama yang diimpor tidak pernah terpakai, sehingga daftar use yang menggantung tidak bersembunyi lama. Konvensi penulisan menempatkan seluruh use di bagian paling atas berkas atau module, diurutkan secara alfabetis dalam satu kelompok, agar pembaca menemukan seluruh dependensi nama dalam satu pandangan.

Mengimpor Banyak Nama dengan Kurung Kurawal Bersarang #

Program nyata jarang cukup dengan satu impor. Menumpuk baris use crate::menu::makanan;, use crate::menu::minuman;, dan seterusnya sah-sah saja, tetapi Rust menyediakan notasi lebih rapat: kurung kurawal yang mengelompokkan item se-induk, lengkap dengan kemampuan bersarang dan alias di dalamnya:

rust
mod menu {
    pub mod makanan {
        pub fn tampilkan() {
            println!("Nasi Goreng Spesial  Rp25000");
        }
    }

    pub mod minuman {
        pub fn tampilkan() {
            println!("Es Teh Manis         Rp5000");
        }

        pub mod spesial {
            pub fn tampilkan() {
                println!("Kopi Susu Gula Aren  Rp18000");
            }
        }
    }
}

use crate::menu::{
    makanan,
    minuman::{tampilkan as tampil_minuman, spesial},
};

fn main() {
    makanan::tampilkan();
    tampil_minuman();
    spesial::tampilkan();
}

Output yang Dihasilkan:

text
Nasi Goreng Spesial  Rp25000
Es Teh Manis         Rp5000
Kopi Susu Gula Aren  Rp18000

Bedah kode di atas:

  1. Baris 21–24 (use crate::menu::{ ... }): satu pernyataan use mengurus dua impor sekaligus. Bagian dalam kurung kurawal dibaca relatif terhadap crate::menu, jadi makanan berarti crate::menu::makanan.
  2. Baris 23 (minuman::{tampilkan as tampil_minuman, spesial},): kurung kurawal kedua bersarang di dalam minuman. Di dalamnya, fungsi tampilkan diimpor sekaligus di-alias menjadi tampil_minuman — wajib, sebab makanan::tampilkan juga sudah hadir di scope melalui jalur module, dan dua nama pendek sama hanya boleh menunjuk item berbeda jika salah satunya di-rename. Module spesial ikut diimpor sebagai nama module biasa.
  3. Baris 27 (makanan::tampilkan();): karena yang diimpor adalah module makanan, fungsinya tetap dipanggil dengan prefix.
  4. Baris 28 (tampil_minuman();): fungsi yang diimpor dan di-alias terpanggil langsung tanpa prefix.
  5. Baris 29 (spesial::tampilkan();): module spesial yang diimpor dari dalam kurung bersarang dapat langsung diprefix — hasil impor bersarang bekerja sama seperti impor tingkat atas.

Alias dengan as #

Keyword as mengganti nama yang dibawa use — berguna ketika nama asli bertabrakan dengan nama lain di scope, atau ketika nama asli terlalu generik di konteks kode kita. Pola klasiknya adalah dua Result dari standard library: std::fmt::Result dan std::io::Result sama-sama bernama Result, sehingga module yang membutuhkan keduanya meng-alias masing-masing — use std::fmt::Result as FmtResult; dan use std::io::Result as IoResult;. Pola yang sama kita pakai untuk memberi nama yang lebih bermakna pada HashMap penyimpan poin pelanggan:

rust
use std::collections::HashMap as PoinPelanggan;

fn main() {
    let mut poin = PoinPelanggan::new();
    poin.insert("Budi", 120);
    poin.insert("Siti", 340);

    println!("Budi memiliki {} poin", poin["Budi"]);
    println!("Siti memiliki {} poin", poin["Siti"]);
}

Output yang Dihasilkan:

text
Budi memiliki 120 poin
Siti memiliki 340 poin

Bedah kode di atas:

  1. Baris 1 (use std::collections::HashMap as PoinPelanggan;): tipe HashMap dari standard library masuk ke scope dengan nama baru PoinPelanggan. Nama asli HashMap tidak ikut hadir — hanya alias-nya.
  2. Baris 4 (let mut poin = PoinPelanggan::new();): pembuatan map memakai alias. Kompiler menerjemahkan PoinPelanggan menjadi std::collections::HashMap pada saat resolusi, jadi tidak ada biaya runtime sama sekali.

Path yang Salah: E0432 #

Keyword use memindahkan titik rawan: salah ketik pada path kini terjadi pada baris impor. Kompilator menangkapnya dengan error E0432 sebelum program berjalan. Perhatikan program berikut yang mengimpor hosting seolah modul itu berada di crate root:

rust
use crate::hosting::add_to_waitlist;

fn main() {
    add_to_waitlist();
}

Pesan error kompilator:

text
error[E0432]: unresolved import `crate::hosting`
 --> main.rs:1:12
  |
1 | use crate::hosting::add_to_waitlist;
  |            ^^^^^^^ could not find `hosting` in the crate root

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0432`.

Pesan unresolved import menyatakan bahwa path crate::hosting tidak ditemukan pada crate root — ingat, hosting sebenarnya tinggal di crate::front_of_house::hosting. Error E0432 juga muncul pada variasi lain: nama item yang salah meski module-nya benar, atau item yang ada namun privat sehingga tidak bisa diimpor. Urutan pemeriksaan yang cepat: pastikan path bertolak dari titik yang benar (crate:: untuk absolut, atau super::/self:: untuk relatif), lalu telusuri setiap segmen path dari kiri ke kanan sambil mencocokkan nama module pada tree.

Ringkasan #

Keyword use membawa nama dari tree module ke scope lokal tanpa menyalin kode: module diimpor untuk pemanggilan ber-prefix, fungsi boleh diimpor langsung, kurung kurawal bersarang merapatkan banyak impor sekaligus, dan as menyediakan alias saat nama bertabrakan atau kurang bermakna. Path impor yang keliru dijawab kompilator dengan E0432 unresolved import beserta lokasi segmen yang gagal. Semua nama yang kita impor sejauh ini berasal dari module yang memang terlihat — padahal sebagian besar isi crate sejatinya privat. Chapter berikutnya membedah keyword pub dan aturan visibility yang mengatur siapa boleh melihat apa di dalam tree.