Modülleri Farklı Dosyalara Ayırma
Bu bölümdeki tüm örneklerde şimdiye kadar birden fazla modülü tek bir dosyada tanımladık. Modüller büyüdüğünde, kod içinde gezinmeyi kolaylaştırmak amacıyla modül tanımlarını ayrı dosyalara taşımak isteyebilirsiniz.
Örneğin, birden fazla restoran modülü barındıran Liste 7-17’deki koddan başlayalım. Tüm modülleri crate kök dosyasında tanımlamak yerine her birini ayrı dosyalara ayıracağız. Bu örnekte crate kök dosyası src/lib.rs dosyasıdır; ancak aynı yöntem, crate kök dosyası src/main.rs olan ikili crate’lerde de işe yarar.
İlk olarak restoran_on_kisim modülünü kendi dosyasına çıkaracağız. restoran_on_kisim modülünün süslü parantezleri arasındaki kodu kaldırıp geriye yalnızca mod restoran_on_kisim; bildirimini bırakın; böylece src/lib.rs dosyası Liste 7-21’deki hâlini alacaktır. Liste 7-22’deki src/restoran_on_kisim.rs dosyasını oluşturana kadar bu kodun derlenmeyeceğini unutmayın.
mod restoran_on_kisim;
pub use crate::restoran_on_kisim::karsilama;
pub fn restoranda_yemek_ye() {
karsilama::bekleme_listesine_ekle();
}
restoran_on_kisim modülünü bildirmeArdından, daha önce süslü parantezlerin içinde yer alan kodu Liste 7-22’de gösterildiği gibi src/restoran_on_kisim.rs adlı yeni bir dosyaya yerleştirin. Derleyici, crate kökünde restoran_on_kisim adında gövdesiz bir modül bildirimiyle (mod restoran_on_kisim;) karşılaştığı için modülün kodunu bu dosyada araması gerektiğini bilir.
pub mod karsilama {
pub fn bekleme_listesine_ekle() {}
}
restoran_on_kisim modülü içindeki tanımlarModül ağacınızda bir dosyayı yüklemek için mod bildirimini yalnızca bir kez kullanmanız gerektiğine dikkat edin. Derleyici, dosyanın projenin bir parçası olduğunu ve mod deyimini koyduğunuz yere göre kodun modül ağacının neresinde konumlandığını bu tek bildirimle öğrenir. Bundan sonra projenizdeki diğer dosyalar, yüklenen bu dosyanın koduna “Modül Ağacındaki Bir Öğeye Başvurmak İçin Yollar” kısmında ele aldığımız gibi modülün bildirildiği konuma giden bir yol üzerinden başvurmalıdır. Başka bir deyişle mod, diğer programlama dillerinde görmüş olabileceğiniz C/C++ #include veya Python/JavaScript import benzeri bir dosya içe aktarma işlemi değildir.
Not: Rust’a yeni başlayanların en sık yaptığı hatalardan biri mod ile use anahtar kelimelerini birbirine karıştırmaktır:
mod restoran_on_kisim;derleyiciye “Bu noktada yeni bir alt modül oluştur ve gövdesini ilgili.rsdosyasından derle” der. Örneğin src/lib.rs içinde zaten bildirdiğinizrestoran_on_kisimmodülünü src/musteri.rs adlı başka bir dosyada kullanmak isterken yanlışlıkla tekrarmod restoran_on_kisim;yazarsanız derleyici src/musteri/restoran_on_kisim.rs adında yeni bir alt modül dosyası arar veerror[E0583]: file not found for module `restoran_on_kisim`hatası verir (hatta hata mesajının altında modülüuse crate::...ile içe aktarmanız gerektiğini hatırlatır).use crate::restoran_on_kisim;ise yeni bir dosya derlemez; modül ağacına daha öncemodile eklenmiş mevcut bir modüle geçerli kapsamda kısa yoldan erişmenizi sağlar. Benzer şekilde hem src/lib.rs hem src/main.rs içeren bir pakette aynı dosyayı her iki kökte demodile bildirmek yerine modülü yalnızca src/lib.rs içinde bildirmeli, src/main.rs içinden ise kütüphane crate’inin adıyla erişmelisiniz.
Şimdi de karsilama modülünü kendi dosyasına çıkaracağız. Bu süreç biraz farklıdır; çünkü karsilama, kök modülün değil restoran_on_kisim modülünün bir alt modülüdür. karsilama modülünün dosyasını, modül ağacındaki ata modüllerinin adını taşıyacak yeni bir dizine — bu örnekte src/restoran_on_kisim dizinine — yerleştireceğiz.
karsilama modülünü taşımaya başlamak için src/restoran_on_kisim.rs dosyasını yalnızca karsilama modülünün bildirimini içerecek şekilde değiştiriyoruz:
pub mod karsilama;
Ardından src/restoran_on_kisim adında bir dizin ve bu dizinin içinde karsilama modülündeki tanımları barındıracak karsilama.rs dosyasını oluşturuyoruz:
pub fn bekleme_listesine_ekle() {}
Eğer bunun yerine karsilama.rs dosyasını doğrudan src dizinine koysaydık derleyici, karsilama.rs içindeki kodun restoran_on_kisim modülünün bir alt modülü olarak değil, doğrudan crate kökünde bildirilen bir karsilama modülünde yer almasını beklerdi. Derleyicinin hangi modülün kodu için hangi dosyaya bakacağını belirleyen kuralları sayesinde, dizin ve dosya yapısı modül ağacıyla birebir örtüşür.
Alternatif Dosya Yolları
Şimdiye kadar Rust derleyicisinin kullandığı en deyimsel dosya yollarını ele aldık; ancak Rust daha eski bir dosya yolu stilini de destekler. Crate kökünde bildirilen restoran_on_kisim adlı bir modül için derleyici, modülün kodunu şu konumlardan birinde arayacaktır:
- src/restoran_on_kisim.rs (ele aldığımız modern düzen)
- src/restoran_on_kisim/mod.rs (daha eski stil, hâlâ desteklenen yol)
restoran_on_kisim modülünün alt modülü olan karsilama adlı bir modül içinse derleyici, modülün kodunu şu konumlardan birinde arayacaktır:
- src/restoran_on_kisim/karsilama.rs (ele aldığımız modern düzen)
- src/restoran_on_kisim/karsilama/mod.rs (daha eski stil, hâlâ desteklenen yol)
Aynı modül için her iki stili birden kullanırsanız derleyici belirsizlik nedeniyle hata verir (E0761). Aynı projedeki farklı modüller için iki stili karışık kullanmaya izin verilir; ancak bu durum projenizde gezinen kişiler için kafa karıştırıcı olabilir.
mod.rs adlı dosyaları kullanan stilin en büyük dezavantajı, projenizde mod.rs adında pek çok dosyanın birikmesi ve bu dosyalar kod editörünüzde aynı anda açık olduğunda sekmeleri birbirinden ayırt etmenin zorlaşmasıdır.
Her modülün kodunu ayrı bir dosyaya taşıdık ve modül ağacı aynı kaldı. restoranda_yemek_ye içindeki fonksiyon çağrıları, tanımlar artık farklı dosyalarda bulunsa bile hiçbir değişiklik gerektirmeden çalışmaya devam edecektir. Bu teknik, modüller büyüdükçe onları yeni dosyalara taşımanıza olanak tanır.
src/lib.rs içindeki pub use crate::restoran_on_kisim::karsilama deyiminin de değişmediğine ve use anahtar kelimesinin crate’in bir parçası olarak hangi dosyaların derlendiği üzerinde hiçbir etkisi olmadığına dikkat edin. mod anahtar kelimesi modülleri bildirir; Rust da o modülün içeriğini oluşturacak kod için modülle aynı adı taşıyan dosyaya bakar.
Not: Modern dosya düzeninin (src/restoran_on_kisim.rs + src/restoran_on_kisim/karsilama.rs) editör sekmelerinde mod.rs karmaşasını önlemesinin yanı sıra pratik bir geliştirme avantajı daha vardır: Başlangıçta alt modülü olmayan src/restoran_on_kisim.rs dosyasına ileride bir alt modül eklemek istediğinizde mevcut dosyayı taşımanıza veya yeniden adlandırmanıza gerek kalmaz; yanına src/restoran_on_kisim/ dizinini açmanız yeterlidir. Eski mod.rs düzeni ise günümüzde özellikle Bölüm 11’de göreceğimiz tests/ dizinindeki ortak entegrasyon testi yardımcı modüllerinde (tests/ortak/mod.rs) özel bir amaca hizmet ettiği için hâlâ bilmeye değerdir.
Özet
Rust, bir paketi birden fazla crate’e ve bir crate’i birden fazla modüle bölmenize, aynı zamanda bir modülde tanımlanan öğelere başka bir modülden başvurabilmenize olanak tanır. Bunu mutlak veya göreli yollar belirterek yapabilirsiniz. Bu yollar, aynı kapsamda bir öğeyi birden fazla kez kullanırken daha kısa bir isim yazabilmeniz için use deyimiyle kapsama dahil edilebilir. Modül kodu varsayılan olarak gizlidir; ancak pub anahtar kelimesini ekleyerek tanımları dışarıya açık hâle getirebilirsiniz.
Bir sonraki bölümde, standart kütüphanede yer alan ve düzenli biçimde yapılandırdığınız kodunuzda kullanabileceğiniz bazı koleksiyon veri yapılarını inceleyeceğiz.