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); }
Ro'yxat 12-1: buyruq qatori argumentlarini vectorga yig'ish va ularni chop etish
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.
argsfunksiyasi va notog'ri UnicodeE'tibor bering, agar biron bir argumentda noto'g'ri Unicode bo'lsa,
std::env::argspanic qo'zg'atadi. Agar dasturingiz noto'g'ri Unicode o'z ichiga olgan argumentlarni qabul qilishi kerak bo'lsa, o'rnigastd::env::args_osdan foydalaning. Bu funksiyaStringqiymatlari o‘rnigaOsStringqiymatlarini ishlab chiqaruvchi iteratorni qaytaradi. Biz bu yerda soddalik uchunstd::env::argsdan foydalanishni tanladik, chunkiOsStringqiymatlari platformalar uchun farq qiladi va ular bilan ishlashStringqiymatlariga 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);
}
Ro'yxat 12-2: So'rov argumenti va fayl yo'li argumentini saqlash uchun o'zgaruvchilar yaratish
Biz vectorni chop etganimizda ko'rganimizdek, dastur nomi vectordagi birinchi qiymatni args[0] oladi, shuning uchun biz 1 indeksidan argumentlarni boshlaymiz. minigrepning 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.