ch07-04-bringing-paths-into-scope-with-the-use-keyword
Yolları use
Anahtar Kelimesi ile Kapsama Alma
Fonksiyonları çağırmak için yolları yazmak zahmetli ve tekrarlı gelebilir. Liste 7-7'de, add_to_waitlist
fonksiyonuna mutlak veya göreceli yol seçmemize bakılmaksızın, add_to_waitlist
'i her çağırmak istediğimizde front_of_house
ve hosting
'i de belirtmek zorunda kaldık. Neyse ki, bu süreci basitleştirmenin bir yolu var: use
anahtar kelimesi ile bir yol için bir kısayol oluşturabiliriz ve ardından o kısayolu kapsam içinde her yerde kullanabiliriz.
use
anahtar kelimesi, modüller arasındaki yolu kısaltarak daha okunabilir ve yönetilebilir hale getirir.
Liste 7-11'de, crate::front_of_house::hosting
modülünü eat_at_restaurant
fonksiyonunun kapsamına alıyoruz, böylece add_to_waitlist
fonksiyonunu çağırmak için sadece hosting::add_to_waitlist
belirtmemiz yeterli oluyor.
{{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-11/src/lib.rs}}
Kapsama use
ve bir yol eklemek, dosya sisteminde sembolik bir bağlantı oluşturmaya benzer. crate
köküne use crate::front_of_house::hosting
ekleyerek, hosting
artık o kapsamda geçerli bir ad haline gelir, sanki hosting
modülü crate kökünde tanımlanmış gibi. use
ile kapsama alınan yollar gizlilik denetiminden geçer, diğer yollar gibi.
Not:
use
anahtar kelimesinin yalnızca bulunduğu belirli kapsamda kısayol oluşturduğunu unutmayın. Liste 7-12,eat_at_restaurant
fonksiyonunucustomer
adlı yeni bir alt modüle taşır, bu dause
ifadesinden farklı bir kapsamdır, bu nedenle işlev gövdesi derlenmeyecektir.
{{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-12/src/lib.rs}}
Derleyici hatası, kısayolun artık customer
modülünde geçerli olmadığını göstermektedir:
{{#include ../listings/ch07-managing-growing-projects/listing-07-12/output.txt}}
Ayrıca use
ifadesinin artık bu kapsamda kullanılmadığına dair bir uyarı da var! Bu sorunu düzeltmek için use
ifadesini customer
modülü içinde de taşıyabilir veya alt customer
modülündeki üst modülde kısayolu super::hosting
ile referans verebilirsiniz.
İdiomatik use
Yolları Oluşturma
Liste 7-11'de, neden use crate::front_of_house::hosting
belirttiğimizi ve ardından eat_at_restaurant
'da hosting::add_to_waitlist
çağırdığımızı merak etmiş olabilirsiniz. Aynı sonucu elde etmek için use
yolunu add_to_waitlist
fonksiyonuna kadar tamamen belirtseydik, Liste 7-13'te olduğu gibi olurdu.
{{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-13/src/lib.rs}}
Her iki Liste 7-11 ve Liste 7-13 aynı görevi yerine getiriyor olsa da, Liste 7-11 use
ile bir fonksiyonu kapsama almanın idiomatik yoludur. Fonksiyonun üst modülünü kapsama almak, fonksiyonu çağırırken üst modülü belirtmemiz gerektiği anlamına gelir. Fonksiyonu çağırırken üst modülü belirtmek, fonksiyonun yerel olarak tanımlanmadığını açıkça belirtirken, tam yolun tekrarını da azaltır. Liste 7-13'teki kod, add_to_waitlist
'in nerede tanımlandığı konusunda belirsizdir.
Diğer yandan, use
ile yapıların, enumların ve diğer öğelerin kapsama alınması söz konusu olduğunda, tam yol belirtmek ideomatik bir yaklaşımdır. Liste 7-14, standart kütüphanenin HashMap
yapısını bir ikili crate kapsamına almanın ideomatik yolunu göstermektedir.
{{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-14/src/main.rs}}
Bu ideomun arkasında güçlü bir neden yoktur: bu, ortaya çıkan bir gelenektir ve insanlar Rust kodunu bu şekilde okumaya ve yazmaya alışmıştır.
Bu ideomun istisnası, use
ifadeleri ile aynı isimde iki öğeyi kapsama almak olduğunda geçerlidir; çünkü Rust bunu kabul etmez.
Liste 7-15, aynı isme ancak farklı üst modüllere sahip olan iki Result
tipini kapsama almanın ve bunlara nasıl atıfta bulunmanın yolunu göstermektedir.
{{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-15/src/lib.rs:here}}
Gördüğünüz gibi, üst modülleri kullanmak iki Result
tipini ayırır. Bunun yerine use std::fmt::Result
ve use std::io::Result
belirtseniz, aynı kapsamda iki Result
tipi olurdu ve Rust hangi Result
'ı kastettiğimizi bilemezdi.
as
Anahtar Kelimesi ile Yeni İsimler Sağlama
use
ile aynı isimde iki türü aynı kapsama almak için başka bir çözüm vardır: yolun ardından as
belirtebiliriz ve tür için yeni bir yerel ad veya takma ad belirtebiliriz. Liste 7-16, Liste 7-15'teki kodu yazmanın başka bir yolunu göstermektedir; as
kullanarak iki Result
tipinden birinin adını değiştiriyoruz.
{{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-16/src/lib.rs:here}}
İkinci use
ifadesinde, std::io::Result
türü için yeni ad olarak IoResult
seçtik. Bu, kapsama aldığımız std::fmt
'ten gelen Result
ile çakışmayacaktır. Liste 7-15 ve Liste 7-16 ideomatik olarak kabul edilir, bu nedenle seçim size kalmıştır!
pub use
ile İsimleri Yeniden İhracat Etme
use
anahtar kelimesi ile bir ismi kapsama aldığımızda, yeni kapsamda mevcut olan isim özel olur. Kodumuzun çağıranlarının o isme, sanki o kodun kapsamına tanımlanmış gibi atıfta bulunabilmesini sağlamak için pub
ve use
'yi birleştirebiliriz. Bu teknik yeniden ihracat etme olarak adlandırılır; çünkü hem bir öğeyi kapsam içine alıyoruz hem de o öğeyi başkalarının kendi kapsamlarına almaları için kullanılabilir hale getiriyoruz.
Liste 7-17, Liste 7-11'deki kodu kök modülündeki use
ifadesini pub use
olarak değiştirilmiş bir şekilde göstermektedir.
{{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-17/src/lib.rs}}
Bu değişiklikten önce, dış kod add_to_waitlist
fonksiyonunu restaurant::front_of_house::hosting::add_to_waitlist()
yolunu kullanarak çağırmak zorundaydı; bu da front_of_house
modülünün pub
olarak işaretlenmesini gerektiriyordu. Artık bu pub use
, hosting
modülünü kök modülden yeniden ihracat ettiğinden, dış kod restaurant::hosting::add_to_waitlist()
yolunu kullanabilir.
Yeniden ihracat etme, kodunuzun iç yapısının, kodunuzu çağıran programcıların düşünme şekli ile farklı olduğu durumlarda yararlıdır.
Örneğin, bu restoran metaforunda, restoranı yöneten insanlar "ön taraf" ve "arka taraf" üzerine düşünürler. Ancak bir restorana giden müşteriler, restoranın bölümlerini o terimlerle düşünmeyeceklerdir. pub use
ile, kodumuzu bir yapı ile yazabilir ancak farklı bir yapıyı açığa çıkarabiliriz. Bu, kütüphanemizin, kütüphane üzerinde çalışan programcılar ve kütüphaneyi çağıran programcılar için iyi yapılandırılmasını sağlar. pub use
ile birlikte crate'nin belgelerini nasıl etkilediğine dair başka bir örneği de 14. Bölümde “Kolay Kullanılabilir Bir Kamu API'si İhracı” kısmında göreceğiz.
Harici Paketleri Kullanma
Bölüm 2'de, rastgele sayılar elde etmek için rand
adlı harici bir paketi kullanan bir tahmin oyunu projesi yazdık. Projelerimizde rand
'i kullanmak için Cargo.toml dosyasına bu satırı ekledik:
{{#include ../listings/ch02-guessing-game-tutorial/listing-02-02/Cargo.toml:9:}}
Cargo.toml dosyasına rand
bağımlılığı eklemek, Cargo'ya rand
paketini ve herhangi bir bağımlılığını crates.io üzerinden indirmesini ve rand
'in projemize ulaşılabilir olmasını sağlar.
Daha sonra rand
tanımlarını paketimizin kapsamına almak için, crate'nin adı olan rand
ile başlayan bir use
satırı ekledik ve kapsama almak istediğimiz öğeleri sıraladık. Hatırlayın ki, 2. Bölümdeki “Rastgele Bir Sayı Üretme” bölümünde, Rng
trait'ini kapsama almış ve rand::thread_rng
fonksiyonunu çağırmıştık:
{{#rustdoc_include ../listings/ch02-guessing-game-tutorial/listing-02-03/src/main.rs:ch07-04}}
Rust topluluğu birçok paketi crates.io üzerinden kullanılabilir hâle getirmiştir ve bunlardan herhangi birini paketinize almak bu aynı adımları içerir: bunları paketin Cargo.toml dosyasında sıralamak ve use
ile paketlerinden öğeleri kapsama almak.
Standart std
kütüphanesinin de paketimiz için harici bir crate olduğunu belirtmek gerekir. Standart kütüphane Rust dili ile birlikte geldiği için, std
'yi Cargo.toml dosyasına eklememize gerek yoktur. Ancak oradan öğeleri paketimizin kapsamına almak için use
ile ona atıfta bulunmamız gerekir. Örneğin, HashMap
için bu satırı kullanırız:
use std::collections::HashMap;
Bu, std
ile başlayan bir mutlak yoldur; bu standart kütüphane crate'inin adıdır.
Büyük use
Listelerini Temizlemek İçin İç İçe Yolları Kullanma
Aynı crate veya aynı modül içinde tanımlanan birden fazla öğeyi kullanıyorsak, her öğeyi ayrı bir satırda listelemek dosyalarımızda çok fazla dikey alana yayılabilir. Örneğin, Liste 2-4'te tahmin oyununda yer alan bu iki use
ifadesi std
'den öğeleri kapsamına alıyor:
{{#rustdoc_include ../listings/ch07-managing-growing-projects/no-listing-01-use-std-unnested/src/main.rs:here}}
Bunun yerine, aynı öğeleri tek bir satırda kapsama almak için iç içe yollar kullanabiliriz. Bunu yapmak için, yolun ortak kısmını belirtir, ardından iki çift iki nokta ve ardından yolların farklı olduğu parçalardan oluşan bir listeyi süslü parantez içine alırız; bu, Liste 7-18'de gösterilmiştir.
{{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-18/src/main.rs:here}}
Büyük programlarda, aynı crate veya modülden birçok öğeyi kapsama almak için iç içe yollar kullanmak, gereken ayrı use
ifadelerinin sayısını büyük ölçüde azaltabilir!
Bir yolun herhangi bir seviyesinde iç içe bir yolu kullanabiliriz; bu, alt yolun paylaşıldığı iki use
ifadesini birleştirirken yararlıdır. Örneğin, Liste 7-19, std::io
'yu kapsama alan bir use
ifadesi ve std::io::Write
'i kapsama alan bir use
ifadesi göstermektedir.
{{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-19/src/lib.rs}}
Bu iki yolun ortak kısmı std::io
'dur ve bu, tamamlanan ilk yoldur. Bu iki yolu tek bir use
ifadesinde birleştirmek için, iç içe yolda self
kullanabiliriz; bu, Liste 7-20'de gösterilmiştir.
{{#rustdoc_include ../listings/ch07-managing-growing-projects/listing-07-20/src/lib.rs}}
Bu satır, std::io
ve std::io::Write
'i kapsama alır.
Glob Operatörü
Bir yolda tanımlanan tüm genel öğeleri kapsama almak istiyorsak, o yolun ardından *
glob operatörünü belirtebiliriz:
use std::collections::*;
Bu use
ifadesi, std::collections
içinde tanımlanan tüm genel öğeleri mevcut kapsamda kapsama alır. Glob operatörünü kullanırken dikkatli olun! Glob, hangi isimlerin kapsamda olduğunu ve programınızdaki bir ismin nerede tanımlandığını anlamayı zorlaştırabilir.
Glob operatörü, genellikle tüm test altını tests
modülüne almak için test yaparken kullanılır; bunu “Test Nasıl Yazılır” bölümünde 11. Bölümde tartışacağız. Glob operatörü bazen prelude deseninin bir parçası olarak da kullanılır: bu desen hakkında daha fazla bilgi için standart kütüphane belgelere
bakabilirsiniz.