ch12-01-accepting-command-line-arguments
Komut Satırı Argümanlarını Alma
Her zamanki gibi, cargo new
ile yeni bir proje oluşturalım. Projemizi minigrep
olarak adlandıracağız, böylece bunu sisteminizde zaten bulunan grep
aracından ayırt edebiliriz.
$ cargo new minigrep
Created binary (application) `minigrep` project
$ cd minigrep
İlk görevimiz minigrep
'in iki komut satırı argümanını kabul etmesini sağlamak: dosya yolu ve aramak için bir dize. Yani, programımızı cargo run
ile çalıştırmak, iki tire kullanarak sonraki argümanların cargo
değil programımız için olduğunu belirtmek, aramak için bir dize vermek ve arama yapacağımız bir dosyanın yolunu belirtmek istiyoruz, şöyle:
$ cargo run -- searchstring example-filename.txt
Şu anda, cargo new
ile oluşturulan program, verdiğimiz argümanları işleyemiyor. :::info Mevcut bazı kütüphaneler, komut satırı argümanlarını kabul eden bir program yazmanıza yardımcı olabilir, ancak bu kavramı yeni öğrendiğiniz için bu yeteneği kendimiz uygulayalım.
Argüman Değerlerini Okuma
minigrep
'in geçirdiğimiz komut satırı argümanlarının değerlerini okuyabilmesi için Rust'ın standart kütüphanesinde sağlanan std::env::args
fonksiyonuna ihtiyacımız var. Bu fonksiyon, minigrep
'e geçirilen komut satırı argümanlarının bir yineleyicisidir. Yineleyicileri Bölüm 13'te tamamen inceleyeceğiz. Şimdilik, yineleyiciler hakkında bilmeniz gereken iki detay var: yineleyiciler bir dizi değer üretir ve bir yineleyici üzerinde collect
metodunu çağırarak onu, yineleyicinin ürettiği tüm öğeleri içeren bir koleksiyona (örneğin bir vektöre) dönüştürebiliriz.
Aşağıdaki kod, minigrep
programınızın geçilen herhangi bir komut satırı argümanını okumasına ve ardından değerleri bir vektörde toplamasına olanak tanır.
{{#rustdoc_include ../listings/ch12-an-io-project/listing-12-01/src/main.rs}}
Öncelikle std::env
modülünü kullanabilmemiz için bir use
ifadesiyle kapsamımıza alıyoruz. std::env::args
fonksiyonunun iki modülde iç içe olduğunu fark edin. :::note Bölüm 7'de tartıştığımız gibi, istenen fonksiyon birden fazla modül içinde iç içe olduğunda, fonksiyonu değil üst modülü kapsamımıza almayı tercih ettik. Bu sayede, std::env
'den diğer fonksiyonları kolayca kullanabiliriz. Aynı zamanda, use std::env::args
ekleyip ardından fonksiyonu sadece args
ile çağırmaktan daha az belirsizdir, çünkü args
, mevcut modülde tanımlanmış bir fonksiyon gibi kolayca yanlış anlaşılabilir.
args
Fonksiyonu ve Geçersiz Unicode
std::env::args
fonksiyonu, herhangi bir argüman geçersiz Unicode içeriyorsa panik yapar. 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 açısından buradastd::env::args
kullanmayı tercih ettik çünküOsString
değerleri platforma göre farklılık gösterir veString
değerlerden daha karmaşık bir şekilde çalışılmaktadır.
main
fonksiyonunun ilk satırında env::args
'i çağırıyoruz ve hemen ardından yineleyiciyi, yineleyicinin ürettiği tüm değerleri içeren bir vektöre dönüştürmek için collect
kullanıyoruz. collect
fonksiyonunu birçok tür koleksiyon oluşturmak için kullanabiliyoruz; bu nedenle args
'in türünü bir dize vektörü istediğimizi belirtmek için açıkça belirtiyoruz. :::tip Rust'ta türleri nadiren belirtmeniz gerekmese de, collect
genellikle hangi tür koleksiyon istediğinizi çıkarsayamadığı için türü belirtmeniz gereken bir fonksiyondur.
Son olarak, vektörü hata ayıklama makrosu ile yazdırıyoruz. Önce hiç argüman ile ardından da iki argüman ile bu kodu çalıştırmayı deneyelim:
{{#include ../listings/ch12-an-io-project/listing-12-01/output.txt}}
{{#include ../listings/ch12-an-io-project/output-only-01-with-args/output.txt}}
Vektördeki ilk değerin "target/debug/minigrep"
olduğunu fark edin, bu da binary'mizin adıdır. Bu, C'deki argümanlar listesinin davranışıyla eşleşiyor ve programların yürütmeleri sırasında çağrıldıkları isimle kullanmalarına olanak tanıyor. :::warning Program adını mesajlarda yazdırmak veya programın davranışını, programın çağrıldığı komut satırı takma adı temelinde değiştirmek için erişiminizin olması genellikle kullanışlıdır. Ancak bu bölümün amaçları doğrultusunda, program adını göz ardı edeceğiz ve yalnızca ihtiyacımız olan iki argümanı saklayacağız.
Argüman Değerlerini Değişkenlerde Saklama
Program şu anda komut satırı argümanları olarak belirtilen değerleri erişebiliyor. Şimdi, bu iki argümanın değerlerini değişkenlerde saklamamız gerekiyor, böylece değerleri programın geri kalanında kullanabiliriz. Bunu, Aşağıdaki Listing 12-2'de yapıyoruz.
{{#rustdoc_include ../listings/ch12-an-io-project/listing-12-02/src/main.rs}}
Vektörü yazdırdığımızda gördüğümüz gibi, programın adı vektörde args[0]
'da ilk değeri alır, bu nedenle argümanlara indeks 1'den başlıyoruz. minigrep
in ilk argümanı, aradığımız dizge olacağından, ilk argümanın referansını query
değişkenine koyuyoruz. İkinci argüman dosya yolu olacağından, ikinci argümanın referansını file_path
değişkenine koyuyoruz.
Bu değişkenlerin değerlerini, kodun istediğimiz gibi çalıştığını kanıtlamak için geçici olarak yazdırıyoruz. Bu programı tekrar test
ve sample.txt
argümanlarıyla çalıştıralım:
{{#include ../listings/ch12-an-io-project/listing-12-02/output.txt}}
Harika, program çalışıyor! İhtiyacımız olan argümanların değerleri doğru değişkenlere kaydediliyor. Daha sonra, kullanıcı hiçbir argüman sağlamadığında gibi bazı potansiyel hatalı durumları ele almak için hata işleme ekleyeceğiz; şimdilik, bu durumu göz ardı edeceğiz ve dosya okuma yetenekleri eklemeye çalışacağız.