Buyruqlar qatori argumentlarini qabul qilish
Keling, har doimgidek, cargo new
bilan yangi loyiha yarataylik. Loyihamizni tizimingizda mavjud boʻlgan grep
konsol dasturidan farqlash uchun uni minigrep
deb ataymiz.
$ cargo new minigrep
Created binary (application) `minigrep` project
$ cd minigrep
Birinchi vazifa minigrep
ni ikkita buyruq qatori argumentlarini qabul qilishdir: fayl yo'li va izlash uchun satr. Ya'ni, biz o'z dasturimizni cargo run
bilan ishga tushirishni xohlaymiz, quyidagi argumentlar cargo
uchun emas, balki dasturimizga tegishli ekanligini ko'rsatadigan ikkita tire(qo'shaloq chiziq), qidirish uchun satr va qidiruv uchun faylga yo'l. ichida, shunga o'xshash:
$ cargo run -- qidiruv-matni namuna-fayl.txt
Hozirda cargo new
tomonidan yaratilgan dastur biz bergan argumentlarni qayta ishlay olmaydi. crates.io-dagi ba'zi mavjud kutubxonalar buyruq qatori argumentlarini qabul qiladigan dastur yozishda yordam berishi mumkin, ammo siz ushbu kontseptsiyani endigina o'rganayotganingiz uchun keling, bu imkoniyatni o'zimiz amalga oshiraylik.
Argument qiymatlarini o'qish
minigrep
ga biz o'tadigan buyruq qatori argumentlarining qiymatlarini o'qishni yoqish uchun bizga Rust standart kutubxonasida taqdim etilgan std::env::args
funksiyasi kerak bo'ladi. Bu funksiya minigrep
ga uzatilgan buyruq qatori argumentlarining iteratorini qaytaradi. Biz iteratorlarni 13-bobda to'liq ko'rib chiqamiz. Hozircha siz iteratorlar haqida faqat ikkita ma'lumotni bilishingiz kerak: iteratorlar bir qator qiymatlarni ishlab chiqaradi va biz uni vector kabi to'plamga(collection) aylantirish uchun iteratorda collect
metodini chaqirishimiz mumkin,iterator ishlab chiqaradigan barcha elementlarni o'z ichiga oladi.
12-1 ro'yxatidagi kod minigrep
dasturingizga unga berilgan har qanday buyruq qatori argumentlarini o'qish va keyin qiymatlarni vectorga yig'ish imkonini beradi.
Fayl nomi: src/main.rs
use std::env; fn main() { let args: Vec<String> = env::args().collect(); dbg!(args); }
Birinchidan, biz std::env
modulini use
statementi bilan qamrab olamiz, shunda uning args
funksiyasidan foydalanamiz. std::env::args
funksiyasi modullarning ikki darajasida joylashganligiga e'tibor bering. Biz 7-bobda muhokama qilganimizdek, istalgan funksiya bir nechta modulda joylashgan bo‘lsa, biz funksiyani emas, balki ota-modulni qamrab olishni tanladik. Shunday qilib, biz std::env
dan boshqa funksiyalardan bemalol foydalanishimiz mumkin. Bu, shuningdek, use std::env::args
ni qo‘shib, so‘ngra funksiyani faqat args
bilan chaqirishdan ko‘ra kamroq noaniqdir, chunki args
joriy modulda aniqlangan funksiya bilan osongina xato qilishi mumkin.
args
funksiyasi va notog'ri UnicodeE'tibor bering, agar biron bir argumentda noto'g'ri Unicode bo'lsa,
std::env::args
panic qo'zg'atadi. Agar dasturingiz noto'g'ri Unicode o'z ichiga olgan argumentlarni qabul qilishi kerak bo'lsa, o'rnigastd::env::args_os
dan foydalaning. Bu funksiyaString
qiymatlari o‘rnigaOsString
qiymatlarini ishlab chiqaruvchi iteratorni qaytaradi. Biz bu yerda soddalik uchunstd::env::args
dan foydalanishni tanladik, chunkiOsString
qiymatlari platformalar uchun farq qiladi va ular bilan ishlashString
qiymatlariga qaraganda murakkabroq.
main
ning birinchi qatorida biz env::args
deb nomlaymiz va iteratorni iterator tomonidan ishlab chiqarilgan barcha qiymatlarni o'z ichiga olgan vectorga aylantirish uchun darhol collect
dan foydalanamiz. Biz ko'p turdagi to'plamlarni(collection) yaratish uchun collect
funksiyasidan foydalanishimiz mumkin, shuning uchun biz stringlar vectorini xohlashimizni ko'rsatish uchun args
turiga aniq izoh beramiz. Rust-da turlarga juda kamdan-kam izoh qo'yishimiz kerak bo'lsa-da, collect
funksiyasi siz tez-tez izohlashingiz kerak bo'lgan funksiyadir, chunki Rust siz xohlagan to'plam turini aniqlay olmaydi.
Nihoyat, debug makrosi yordamida vectorni chop etamiz. Keling, kodni avval argumentsiz, keyin esa ikkita argument bilan ishga tushirishga harakat qilaylik:
$ cargo run
Compiling minigrep v0.1.0 (file:///projects/minigrep)
Finished dev [unoptimized + debuginfo] target(s) in 0.61s
Running `target/debug/minigrep`
[src/main.rs:5] args = [
"target/debug/minigrep",
]
$ cargo run -- anor mevalar
Compiling minigrep v0.1.0 (file:///projects/minigrep)
Finished dev [unoptimized + debuginfo] target(s) in 1.57s
Running `target/debug/minigrep anor mevalar`
[src/main.rs:5] args = [
"target/debug/minigrep",
"anor",
"mevalar",
]
E'tibor bering, vectordagi birinchi qiymat "target/debug/minigrep"
bo'lib, bu bizning ikkilik(binary) faylimiz nomidir. Bu C dagi argumentlar ro'yxatining xatti-harakatiga mos keladi, bu dasturlarga ularni bajarishda chaqirilgan nomdan foydalanishga imkon beradi. Agar siz uni xabarlarda chop qilmoqchi bo'lsangiz yoki dasturni chaqirish uchun qanday buyruq qatori taxalluslari(alias) ishlatilganiga qarab dasturning harakatini o'zgartirmoqchi bo'lsangiz, dastur nomiga kirish ko'pincha qulaydir. Ammo ushbu bobning maqsadlari uchun biz buni e'tiborsiz qoldiramiz va faqat bizga kerak bo'lgan ikkita argumentni saqlaymiz.
Argument qiymatlarini o'zgaruvchilarda saqlash
Dastur hozirda buyruq qatori argumentlari sifatida ko'rsatilgan qiymatlarga kirish imkoniyatiga ega. Endi biz ikkita argumentning qiymatlarini o'zgaruvchilarda saqlashimiz kerak, shuning uchun biz dasturning qolgan qismida qiymatlardan foydalanishimiz mumkin. Biz buni 12-2 ro'yxatda qilamiz.
Fayl nomi: src/main.rs
use std::env;
fn main() {
let args: Vec<String> = env::args().collect();
let sorov = &args[1];
let fayl_yoli = &args[2];
println!("{} qidirilmoqda", sorov);
println!("{} faylida", fayl_yoli);
}
Biz vectorni chop etganimizda ko'rganimizdek, dastur nomi vectordagi birinchi qiymatni args[0]
oladi, shuning uchun biz 1
indeksidan argumentlarni boshlaymiz. minigrep
ning birinchi argumenti biz qidirayotgan satrdir, shuning uchun biz birinchi argumentga referenceni sorov
o‘zgaruvchisiga qo‘yamiz. Ikkinchi argument fayl yo'li bo'ladi, shuning uchun biz fayl_yoli
o'zgaruvchisiga ikkinchi argumentga reference qilamiz.
Kod biz xohlagandek ishlayotganini isbotlash uchun biz ushbu o'zgaruvchilarning qiymatlarini vaqtincha chop qilamiz. test
va namuna.txt
argumentlari bilan ushbu dasturni qayta ishga tushiramiz:
$ cargo run -- test namuna.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`
test qidirilmoqda
namuna.txt faylida
Ajoyib, dastur ishlayapti! Bizga kerak bo'lgan argumentlarning qiymatlari to'g'ri o'zgaruvchilarga saqlanmoqda. Keyinchalik ba'zi potentsial noto'g'ri vaziyatlarni hal qilish uchun xatolarni qayta ishlash usullarini qo'shamiz, masalan, foydalanuvchi hech qanday argument keltirmasa; Hozircha biz bu holatni e'tiborsiz qoldiramiz va uning o'rniga fayllarni o'qish imkoniyatlarini qo'shish ustida ishlaymiz.