Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Modüllerle Kapsam ve Gizliliği Kontrol Etme

Bu bölümde modüllerden ve modül sisteminin diğer parçalarından, yani öğeleri isimlendirmenizi sağlayan yollardan (paths), bir yolu kapsama getiren use anahtar kelimesinden ve öğeleri herkese açık hale getiren pub anahtar kelimesinden bahsedeceğiz. Ayrıca as anahtar kelimesini, harici paketleri ve glob operatörünü de ele alacağız.

Modüller Kopya Kağıdı (Cheat Sheet)

Modüllerin ve yolların detaylarına girmeden önce, burada modüllerin, yolların, use anahtar kelimesinin ve pub anahtar kelimesinin derleyicide nasıl çalıştığına ve çoğu geliştiricinin kodlarını nasıl düzenlediğine dair hızlı bir başvuru kılavuzu (quick reference) sunuyoruz. Bu bölüm boyunca bu kuralların her birini örneklerle inceleyeceğiz, ancak modüllerin nasıl çalıştığını hatırlamak için burası harika bir başvuru noktasıdır.

  • Crate kökünden başlayın: Bir crate’i derlerken, derleyici önce derlenecek kodu bulmak için crate kök dosyasına (genellikle bir kütüphane crate’i için src/lib.rs ve bir ikili crate için src/main.rs) bakar.
  • Modülleri bildirmek (declaring modules): Crate kök dosyasında yeni modüller bildirebilirsiniz; diyelim ki mod bahce; ile bir “bahce” modülü bildirdiniz. Derleyici, bu modülün kodunu şu konumlarda arayacaktır:
    • Satır içi, mod bahce’den sonraki noktalı virgül yerine konulan süslü parantezlerin içinde
    • src/bahce.rs dosyasında
    • src/bahce/mod.rs dosyasında
  • Alt modülleri bildirmek (declaring submodules): Crate kökü dışındaki herhangi bir dosyada alt modüller bildirebilirsiniz. Örneğin, src/bahce.rs içinde mod sebzeler; bildirebilirsiniz. Derleyici, alt modülün kodunu ana modülün adını taşıyan dizinde şu konumlarda arayacaktır:
    • Satır içi, doğrudan mod sebzeler’den sonra, noktalı virgül yerine süslü parantezlerin içinde
    • src/bahce/sebzeler.rs dosyasında
    • src/bahce/sebzeler/mod.rs dosyasında
  • Modüllerdeki kodların yolları: Bir modül crate’inizin bir parçası olduğunda, gizlilik kuralları izin verdiği sürece, kodun yolunu kullanarak o crate’in başka bir yerinden o modüldeki koda başvurabilirsiniz. Örneğin, bahce sebzeler modülündeki bir Kuskonmaz (Asparagus) türü crate::bahce::sebzeler::Kuskonmaz adresinde (yolunda) bulunacaktır.
  • Gizli ve açık: Bir modül içindeki kod varsayılan olarak üst modüllerinden gizlidir. Bir modülü açık hale getirmek için mod yerine pub mod ile bildirin. Açık bir modül içindeki öğeleri de açık hale getirmek için bildirimlerinden (declaration) önce pub kullanın.
  • use anahtar kelimesi: Bir kapsam içinde, use anahtar kelimesi uzun yolların tekrarını azaltmak için öğelere kısayollar oluşturur. crate::bahce::sebzeler::Kuskonmaz’a başvurabilen herhangi bir kapsamda, use crate::bahce::sebzeler::Kuskonmaz; ile bir kısayol oluşturabilirsiniz; ve o andan itibaren bu türü o kapsamda kullanmak için yalnızca Kuskonmaz yazmanız yeterlidir.

Burada, bu kuralları gösteren arka_bahce (backyard) adlı bir ikili crate oluşturuyoruz. Crate’in yine arka_bahce adını taşıyan dizini, şu dosyaları ve dizinleri içerir:

arka_bahce
├── Cargo.lock
├── Cargo.toml
└── src
    ├── bahce
    │   └── sebzeler.rs
    ├── bahce.rs
    └── main.rs

Bu durumda crate kök dosyası src/main.rs’dir ve şunları içerir:

Filename: src/main.rs
use crate::bahce::sebzeler::Kuskonmaz;

pub mod bahce;

fn main() {
    let bitki = Kuskonmaz {};
    println!("{bitki:?} yetiştiriyorum!");
}

pub mod bahce; satırı, derleyiciye src/bahce.rs dosyasında bulduğu kodu dahil etmesini söyler:

Filename: src/bahce.rs
pub mod sebzeler;

Burada, pub mod sebzeler;, src/bahce/sebzeler.rs dosyasındaki kodun da dahil edildiği anlamına gelir. O kod da şudur:

#[derive(Debug)]
pub struct Kuskonmaz {}

Şimdi bu kuralların detaylarına girelim ve pratikte nasıl uygulandıklarını gösterelim!

İlgili Kodu Modüllerde Gruplama

Modüller, okunabilirlik ve kolay yeniden kullanım için bir crate içindeki kodu düzenlememize olanak tanır. Modüller aynı zamanda öğelerin gizliliğini kontrol etmemizi sağlar çünkü bir modül içindeki kod varsayılan olarak gizlidir. Gizli öğeler, dışarıdan kullanıma açık olmayan dahili (internal) uygulama ayrıntılarıdır. Modülleri ve içlerindeki öğeleri açık hale getirmeyi seçebiliriz, bu da onları açığa çıkararak harici kodların onları kullanmasına ve onlara bağımlı olmasına olanak tanır.

Örnek olarak, bir restoranın işlevselliğini sağlayan bir kütüphane (library) crate’i yazalım. Fonksiyonların imzalarını tanımlayacağız, ancak bir restoranın uygulanmasından ziyade kodun organizasyonuna odaklanmak için gövdelerini boş bırakacağız.

Restoran sektöründe, bir restoranın bazı bölümleri ön kısım (front of house), diğerleri ise arka kısım (back of house) olarak adlandırılır. Ön kısım müşterilerin bulunduğu yerdir; burası karşılamanın (hosts) müşterileri oturttuğu, servis elemanlarının (servers) siparişleri ve ödemeleri aldığı ve barmenlerin içecekleri hazırladığı yeri kapsar. Arka kısım ise şeflerin ve aşçıların mutfakta çalıştığı, bulaşıkçıların temizlik yaptığı ve yöneticilerin idari işleri yürüttüğü yerdir.

Crate’imizi bu şekilde yapılandırmak için, fonksiyonlarını iç içe geçmiş modüller halinde düzenleyebiliriz. cargo new restoran --lib komutunu çalıştırarak restoran adında yeni bir kütüphane oluşturun. Ardından, bazı modülleri ve fonksiyon imzalarını tanımlamak için Liste 7-1’deki kodu src/lib.rs dosyasına girin; bu kod restoranın ön kısmını temsil eder.

Filename: src/lib.rs
mod restoran_on_kisim {
    mod karsilama {
        fn bekleme_listesine_ekle() {}

        fn masaya_oturt() {}
    }

    mod servis {
        fn siparis_al() {}

        fn siparis_servis_et() {}

        fn odeme_al() {}
    }
}
Listing 7-1: İçinde fonksiyonlar barındıran başka modüller içeren bir restoran_on_kisim modülü

mod anahtar kelimesini ve ardından modülün adını (bu durumda restoran_on_kisim) kullanarak bir modül tanımlarız. Modülün gövdesi daha sonra süslü parantezlerin içine girer. Modüllerin içine, bu durumda karsilama ve servis modüllerinde olduğu gibi başka modüller yerleştirebiliriz. Modüller ayrıca struct’lar, enum’lar, sabitler (constants), trait’ler ve Liste 7-1’de olduğu gibi fonksiyonlar gibi diğer öğeler için tanımlar da barındırabilir.

Modülleri kullanarak, birbiriyle ilişkili tanımları bir arada gruplayabilir ve neden ilişkili olduklarını isimlendirebiliriz. Bu kodu kullanan programcılar, tüm tanımları okumak zorunda kalmadan, gruplara göre kod içinde gezinebilirler ve bu da onlarla alakalı tanımları bulmalarını kolaylaştırır. Bu koda yeni işlevsellik ekleyen programcılar, programın düzenli kalması için kodu nereye yerleştireceklerini bileceklerdir.

Daha önce, src/main.rs ve src/lib.rs dosyalarının crate kökleri (crate roots) olarak adlandırıldığından bahsetmiştik. Bu şekilde adlandırılmalarının nedeni, bu iki dosyadan herhangi birinin içeriğinin, crate’in modül yapısının kökünde (bu yapı modül ağacı - module tree olarak bilinir) crate adında bir modül oluşturmasıdır.

Liste 7-2, Liste 7-1’deki yapının modül ağacını göstermektedir.

crate
 └── restoran_on_kisim
     ├── karsilama
     │   ├── bekleme_listesine_ekle
     │   └── masaya_oturt
     └── servis
         ├── siparis_al
         ├── siparis_servis_et
         └── odeme_al
Listing 7-2: Liste 7-1’deki kod için modül ağacı

Bu ağaç, bazı modüllerin diğer modüllerin içine nasıl yuvalandığını (iç içe geçtiğini) gösterir; örneğin, karsilama, restoran_on_kisim’in içine yuvalanmıştır. Ağaç ayrıca bazı modüllerin kardeş (siblings) olduğunu, yani aynı modül içinde tanımlandıklarını gösterir; karsilama ve servis, restoran_on_kisim içinde tanımlanmış kardeş modüllerdir. Eğer A modülü B modülünün içindeyse, A modülünün B modülünün çocuğu ve B modülünün A modülünün ebeveyni olduğunu söyleriz. Tüm modül ağacının, örtük (implicit) crate adlı modülün altında köklendiğine (rooted) dikkat edin.

Modül ağacı, bilgisayarınızdaki dosya sisteminin dizin ağacını hatırlatabilir; bu çok yerinde bir karşılaştırmadır! Tıpkı dosya sistemindeki dizinler gibi, kodunuzu düzenlemek için de modülleri kullanırsınız. Ve bir dizindeki dosyalar gibi, modüllerimizi bulmanın da bir yoluna ihtiyacımız var.