Mendefinisikan Modul untuk Mengontrol Ruang Lingkup
Pada bagian ini, kita akan membahas tentang modul dan bagian-bagian lain dari sistem modul, yaitu paths yang memungkinkan Anda memberi nama pada item, dan kata kunci use
yang membawa path ke dalam cakupan.
Pertama, kita akan memulai dengan daftar aturan untuk referensi mudah saat Anda mengorganisir kode Anda di masa mendatang. Kemudian kita akan menjelaskan setiap aturan secara detail.
Modules Cheat Sheet
Di sini kami menyediakan referensi cepat tentang bagaimana modul, path, dan kata kunci use
bekerja dalam kompiler, serta bagaimana sebagian besar pengembang mengatur kode mereka. Kami akan menjelaskan contoh dari setiap aturan ini sepanjang bab ini, namun ini adalah tempat yang bagus untuk dilihat kembali sebagai pengingat tentang bagaimana modul bekerja. Anda dapat membuat proyek Scarb baru dengan scarb new backyard
untuk mengikuti langkah-langkahnya.
-
Mulai dari crate roo: Saat mengompilasi sebuah crate, kompiler pertama-tama mencari kode yang akan dikompilasi dalam berkas akar crate (src/lib.cairo).
-
Declaring modules: Di dalam berkas crate root, Anda dapat mendeklarasikan modul baru; misalnya, Anda mendeklarasikan modul "garden" dengan
mod garden;
. Kompiler akan mencari kode modul ini di tempat-tempat berikut:-
Inline, within curly brackets that replace the semicolon following
mod garden
.// crate root file (src/lib.cairo) mod garden { // code defining the garden module goes here }
-
In the file src/garden.cairo.
-
-
Declaring modules: Di dalam berkas selain akar crate, Anda dapat mendeklarasikan submodul. Sebagai contoh, Anda mungkin mendeklarasikan
mod vegetables;
di src/garden.cairo. Kompiler akan mencari kode submodul ini dalam direktori yang dinamai sesuai dengan modul induk di tempat-tempat berikut:-
Secara langsung, langsung setelah
mod vegetables
, di dalam tanda kurung kurawal sebagai pengganti titik koma.// src/garden.cairo file mod vegetables { // code defining the vegetables submodule goes here }
-
In the file src/garden/vegetables.cairo.
-
-
Paths to code in modules: Once a module is part of your crate, you can refer to code in that module from anywhere else in that same crate, using the path to the code. For example, an
Asparagus
type in thevegetables
submodule would be found atcrate::garden::vegetables::Asparagus
. -
Private vs public: Code within a module is private from its parent modules by default. This means that it may only be accessed by the current module and its descendants. To make a module public, declare it with
pub mod
instead ofmod
. To make items within a public module public as well, usepub
before their declarations. Cairo also provides thepub(crate)
keyword, allowing an item or module to be only visible within the crate in which the definition is included. -
The
use
keyword: Within a scope, theuse
keyword creates shortcuts to items to reduce repetition of long paths. In any scope that can refer tocrate::garden::vegetables::Asparagus
, you can create a shortcut withuse crate::garden::vegetables::Asparagus;
and from then on you only need to writeAsparagus
to make use of that type in the scope.
Di sini kita membuat sebuah crate yang bernama backyard
yang mengilustrasikan aturan-aturan ini. Direktori crate ini, yang juga bernama backyard
, berisi file-file dan direktori-direktori berikut:
backyard/
├── Scarb.toml
└── src
├── garden
│ └── vegetables.cairo
├── garden.cairo
└── lib.cairo
Berkas crate root dalam kasus ini adalah src/lib.cairo, dan berisi:
Filename: src/lib.cairo
pub mod garden;
use crate::garden::vegetables::Asparagus;
fn main() {
let plant = Asparagus {};
println!("I'm growing {:?}!", plant);
}
The pub mod garden;
line imports the garden
module. Using pub
to make garden
publicly accessible, or pub(crate)
if you really want to make garden
only available for your crate, is optional to run our program here, as the main
function resides in the same module as pub mod garden;
declaration. Nevertheless, not declaring garden
as pub
will make it not accessible from any other package. This line tells the compiler to include the code it finds in src/garden.cairo, which is:
Filename: src/garden.cairo
pub mod vegetables;
Here, pub mod vegetables;
means the code in src/garden/vegetables.cairo is included too. That code is:
#[derive(Drop, Debug)]
pub struct Asparagus {}
The line use crate::garden::vegetables::Asparagus;
lets us bring the Asparagus
type into scope, so we can use it in the main
function.
Sekarang mari kita masuk ke dalam detail aturan-aturan ini dan tunjukkan penggunaannya dalam praktek!
Mengelompokkan Kode yang Terkait dalam Modul
Modules let us organize code within a crate for readability and easy reuse. Modules also allow us to control the privacy of items, because code within a module is private by default. Private items are internal implementation details not available for outside use. We can choose to make modules and the items within them public, which exposes them to allow external code to use and depend on them.
As an example, let’s write a library crate that provides the functionality of a restaurant. We’ll define the signatures of functions but leave their bodies empty to concentrate on the organization of the code, rather than the implementation of a restaurant.
Dalam industri restoran, beberapa bagian dari sebuah restoran disebut sebagai front of house dan yang lainnya disebut sebagai back of house. Front of house adalah tempat di mana para pelanggan berada; ini meliputi tempat di mana tuan rumah duduknya pelanggan, pelayan mengambil pesanan dan pembayaran, dan penjaga bar membuat minuman. Back of house adalah tempat di mana koki bekerja di dapur, pembersih peralatan membersihkan, dan manajer melakukan pekerjaan administratif.
To structure our crate in this way, we can organize its functions into nested modules. Create a new package named restaurant by running scarb new restaurant
; then enter the code in Listing 7-1 into src/lib.cairo to define some modules and function signatures. Here’s the front of house section:
Filename: src/lib.cairo
mod front_of_house {
mod hosting {
fn add_to_waitlist() {}
fn seat_at_table() {}
}
mod serving {
fn take_order() {}
fn serve_order() {}
fn take_payment() {}
}
}
Listing 7-1: A front_of_house
module containing other modules that then contain functions
We define a module with the mod
keyword followed by the name of the module (in this case, front_of_house
). The body of the module then goes inside curly brackets. Inside modules, we can place other modules, as in this case with the modules hosting
and serving
. Modules can also hold definitions for other items, such as structs, enums, constants, traits, and functions.
Dengan menggunakan modul, kita dapat mengelompokkan definisi-definisi terkait bersama dan menjelaskan mengapa mereka terkait. Para programmer yang menggunakan kode ini dapat menjelajahi kode berdasarkan grup-grup tersebut daripada harus membaca melalui semua definisi, sehingga lebih mudah untuk menemukan definisi yang relevan bagi mereka. Para programmer yang menambahkan fungsionalitas baru ke dalam kode ini akan tahu di mana meletakkan kode tersebut untuk menjaga keorganisasian program.
Earlier, we mentioned that src/lib.cairo is called the crate root. The reason for this name is that the content of this file forms a module named after the crate name at the root of the crate’s module structure, known as the module tree.
Listing 7-2 menunjukkan pohon modul untuk struktur pada Daftar 7-1.
restaurant
└── front_of_house
├── hosting
│ ├── add_to_waitlist
│ └── seat_at_table
└── serving
├── take_order
├── serve_order
└── take_payment
Listing 7-2: The module tree for the code in Listing 7-1
This tree shows how some of the modules nest inside one another; for example, hosting
nests inside front_of_house
. The tree also shows that some modules are siblings to each other, meaning they’re defined in the same module; hosting
and serving
are siblings defined within front_of_house
. If module A is contained inside module B, we say that module A is the child of module B and that module B is the parent of module A. Notice that the entire module tree is rooted under the explicit name of the crate restaurant.
Pohon modul mungkin mengingatkan Anda pada pohon direktori dalam sistem file di komputer Anda; perbandingan ini sangat tepat! Sama seperti direktori dalam sistem file, Anda menggunakan modul untuk mengatur kode Anda. Dan sama seperti file dalam sebuah direktori, kita memerlukan cara untuk menemukan modul-modul kita.