Komut Satırı Argümanlarını Kabul Etme
Her zaman olduğu gibi cargo new
ile yeni bir proje oluşturalım. Sisteminizde mevcut olabilecek grep
aracıyla çakışmaması için projemizi minigrep
olarak adlandıracağız
$ cargo new minigrep
Created binary (application) `minigrep` project
$ cd minigrep
İlk görev, minigrep
'in iki komut satırı argümanını kabul etmesini sağlamaktır:
dosya adı ve aranacak bir dize. Yani, programımızı cargo run
'la, aranacak bir dize ve aranacak bir
dosyanın yolu ile çalıştırabilmek istiyoruz, şunun gibi:
$ cargo run searchstring example-filename.txt
Şu anda, cargo new
tarafından oluşturulan program, ona verdiğimiz argümanları işleyemiyor.
crates.io'daki bazı mevcut kütüphaneler, komut satırı argümanlarını kabul eden bir program yazmaya yardımcı olabilir,
ancak bu kavramı yeni öğrendiğiniz için, hadi bunu kendimiz sürekleyelim.
Argüman Değerlerini Okumak
minigrep
'in kendisine ilettiğimiz komut satırı argümanlarının değerlerini okumasını sağlamak için,
Rust'ın standart kütüphanesinde bulunan std::env::args
fonksiyonuna ihtiyacımız olacak.
Bu fonksiyon, minigrep
'e iletilen komut satırı argümanlarının bir yineleyicisini döndürür.
Bölüm 13'te yineleyicileri tam olarak ele alacağız. Şimdilik, yineleyiciler hakkında yalnızca iki ayrıntıyı bilmeniz gerekir:
yineleyiciler bir dizi değer üretir ve bir yineleyicide onu bir koleksiyona dönüştürmek için collect
metodunu çağırabiliriz,
örneğin: yineleyicinin ürettiği tüm öğeleri içeren vektör.
Liste 12-1'deki kod, minigrep
programınızın kendisine iletilen herhangi bir komut satırı argümanını okumasını ve
ardından değerleri bir vektörde toplamasını sağlar.
Dosya adı: src/main.rs
use std::env; fn main() { let args: Vec<String> = env::args().collect(); println!("{:?}", args); }
İlk olarak, args
fonksiyonunu kullanabilmemiz için std::env
modülünü use
ifade yapısı ile kapsama alıyoruz.
std::env::args
fonksiyonunun iki modül düzeyinde tutuluyor olduğuna dikkat edin.
Bölüm 7'de tartıştığımız gibi, istenen fonksiyonun birden fazla modülde iç içe olduğu durumlarda,
ana modülü fonksiyon yerine kapsama almak gelenekseldir. Bunu yaparak, std::env
'deki diğer fonksiyonları kolayca kullanabiliriz.
Ayrıca use std::env::args
eklemekten ve ardından fonksiyonu yalnızca args
ile çağırmaktan daha az belirsizdir,
çünkü arg
'ler kolayca geçerli modülde tanımlanan bir fonksiyonla karıştırılabilir.
args
Fonksiyonu ve Geçersiz UnicodeHerhangi bir argüman geçersiz Unicode içeriyorsa
std::env::args
öğesinin panikleyeceğini unutmayın. Programınızın geçersiz Unicode içeren argümanları kabul etmesi gerekiyorsa, bunun yerinestd::env::args_os
kullanın. Bu fonksiyon,String
değerleri yerineOsString
değerleri üreten bir yineleyici döndürür. Basitlik için buradastd::env::args
kullanmayı seçtik, çünküOsString
değerleri platforma göre farklılık gösterir ve onlarla çalışmakString
değerlerinden daha karmaşıktır.
main
'in ilk satırında, env::args
'ı çağırırız ve yineleyiciyi yineleyici tarafından üretilen tüm değerleri
içeren bir vektöre dönüştürmek için collect
kullanırız. Pek çok türde koleksiyon oluşturmak için collect
fonksiyonunu kullanabiliriz, bu nedenle bir dizi vektörü istediğimizi belirtmek için açıkça arg
türüne açıklama ekleriz.
Rust'ta türlere çok nadiren açıklama eklememiz gerekse de, collect
, genellikle açıklama eklemeniz gereken bir fonksiyondur çünkü Rust,
istediğiniz koleksiyon türünü çıkaramaz.
Son olarak, vektörü hata ayıklama biçimlendiricisini (:?
) kullanarak yazdırırız.
Kodu önce bağımsız değişken olmadan ve ardından iki bağımsız değişkenle çalıştırmayı deneyelim:
$ cargo run
Compiling minigrep v0.1.0 (file:///projects/minigrep)
Finished dev [unoptimized + debuginfo] target(s) in 0.61s
Running `target/debug/minigrep`
["target/debug/minigrep"]
$ cargo run needle haystack
Compiling minigrep v0.1.0 (file:///projects/minigrep)
Finished dev [unoptimized + debuginfo] target(s) in 1.57s
Running `target/debug/minigrep needle haystack`
["target/debug/minigrep", "needle", "haystack"]
Vektördeki ilk değerin, ikili dosyamızın adı olan "target/debug/minigrep"
olduğuna dikkat edin.
Bu, programların yürütülürken çağrıldıkları adı kullanmasına izin vererek,
C'deki argüman listesinin davranışıyla eşleşir. Mesajlarda yazdırmak veya programı çağırmak için
hangi komut satırı diğer adının kullanıldığına bağlı olarak programın davranışını değiştirmek istemeniz durumunda,
program adına erişiminiz olması genellikle uygundur. Ancak bu bölümün amaçları doğrultusunda, onu görmezden geleceğiz
ve yalnızca ihtiyacımız olan iki argümanı kaydedeceğiz.
Değişkenlerde Argüman Değerlerini Tutma
Program şu anda komut satırı argümanları olarak belirtilen değerlere erişebilir. Şimdi değerleri programın geri kalanında kullanabilmemiz için iki argümanın değerlerini değişkenlere kaydetmemiz gerekiyor. Bunu Liste 12-2'de yapıyoruz.
Dosya adı: src/main.rs
use std::env;
fn main() {
let args: Vec<String> = env::args().collect();
let query = &args[1];
let filename = &args[2];
println!("Searching for {}", query);
println!("In file {}", filename);
}
Vektörü yazdırdığımızda gördüğümüz gibi, programın adı args[0]
'daki vektördeki ilk değeri alır,
dolayısıyla argümanları indeks 1
'den başlatıyoruz. minigrep
'in aldığı ilk argüman, aradığımız dizgidir,
bu yüzden değişken sorgusundaki ilk argümana bir referans koyduk. İkinci argüman dosya adı olacaktır,
bu yüzden dosya adı değişkenine ikinci argümana bir referans koyduk.
Kodun istediğimiz gibi çalıştığını kanıtlamak için bu değişkenlerin değerlerini geçici olarak yazdırırız.
Bu programı test
ve sample.txt
argümanları ile tekrar çalıştıralım:
$ cargo run test sample.txt
Compiling minigrep v0.1.0 (file:///projects/minigrep)
Finished dev [unoptimized + debuginfo] target(s) in 0.0s
Running `target/debug/minigrep test sample.txt`
Searching for test
In file sample.txt
Harika, program çalışıyor! İhtiyacımız olan argümanların değerleri doğru değişkenlere kaydediliyor. Daha sonra, örneğin kullanıcının hiçbir argüman sağlamaması gibi bazı olası hatalı durumlarla başa çıkmak için bazı hata işleme ekleyeceğiz, şimdilik bu durumu görmezden geleceğiz ve bunun yerine dosya okuma yetenekleri eklemeye çalışacağız.