flag paketi
Ko'plab Go dasturlari (ayniqsa CLI — buyruq qatori vositalari) ishga tushirilganda turli sozlamalarni argument sifatida qabul qiladi, masalan: myapp -port=8080 -debug. flag — aynan shunday buyruq qatori argumentlarini (flag'larni) tahlil qilish uchun mo'ljallangan standart paket.
import "flag"
[!NOTE]
os.Args(oldingi darsda ko'rgan edik) orqali ham argumentlarni o'qish mumkin, lekinflagularni avtomatik ravishda kerakli turga (string,int,bool) aylantiradi, standart qiymat beradi va-h/-helporqali avtomatik yordam xabarini ham yaratib beradi.
package main
import (
"flag"
"fmt"
)
func main() {
// parametrlar: flag nomi, standart qiymat, tavsif (yordam xabarida ko'rinadi)
name := flag.String("name", "dunyo", "salomlashish uchun ism")
age := flag.Int("age", 0, "yosh")
verbose := flag.Bool("verbose", false, "batafsil chiqish rejimi")
// barcha flag'larni buyruq qatoridan o'qib, yuqoridagi o'zgaruvchilarga joylaydi
flag.Parse()
// e'tibor bering: name, age, verbose — bularning barchasi KO'RSATKICH (*string, *int, *bool)!
fmt.Println("Salom,", *name)
fmt.Println("Yosh:", *age)
fmt.Println("Batafsil rejim:", *verbose)
}
Dasturni quyidagicha ishga tushirsak:
myapp -name=Ali -age=25 -verbose
Natija:
Salom, Ali
Yosh: 25
Batafsil rejim: true
Agar flag'lar berilmasa, standart qiymatlar ishlatiladi:
myapp
Natija:
Salom, dunyo
Yosh: 0
Batafsil rejim: false
[!IMPORTANT]
flag.String(),flag.Int(),flag.Bool()— bularning barchasi ko'rsatkich (*string,*int,*bool) qaytaradi, oddiy qiymat emas! Shuning uchun ularning haqiqiy qiymatiga murojaat qilishda har doim*(dereferensiya) operatoridan foydalanish kerak:*name,*age.
StringVar()Agar ko'rsatkich bilan ishlash noqulay tuyulsa, flag qiymatini oldindan e'lon qilingan oddiy o'zgaruvchiga to'g'ridan-to'g'ri "bog'lash" ham mumkin:
package main
import (
"flag"
"fmt"
)
func main() {
var port int
// port o'zgaruvchisining manzili beriladi, u avtomatik to'ldiriladi
flag.IntVar(&port, "port", 8080, "server porti")
flag.Parse()
fmt.Println("Server porti:", port) // endi * kerak emas, oddiy int
}
Natija (standart qiymat bilan ishga tushirilsa):
Server porti: 8080
flag.Args()Agar dasturga flag'lardan tashqari, oddiy qo'shimcha argumentlar ham berilsa (masalan, fayl nomlari), ularni flag.Args() orqali olish mumkin:
package main
import (
"flag"
"fmt"
)
func main() {
verbose := flag.Bool("verbose", false, "batafsil chiqish")
flag.Parse()
fmt.Println("Verbose:", *verbose)
fmt.Println("Qolgan argumentlar:", flag.Args())
}
Ishga tushirish:
myapp -verbose fayl1.txt fayl2.txt
Natija:
Verbose: true
Qolgan argumentlar: [fayl1.txt fayl2.txt]
Bu, masalan, myapp -verbose fayl1.txt fayl2.txt kabi — flag'lardan keyin fayl nomlari beriladigan CLI vositalar yaratishda foydalanadi.
flag paketi orqali yaratilgan har qanday dastur -h yoki -help bilan ishga tushirilsa, avtomatik ravishda barcha flag'lar va ularning tavsiflari ro'yxatini chiqaradi — buni qo'shimcha kod yozmasdan bepul olamiz:
myapp -h
Natija (yuqoridagi 1-misoldagi flag'lar uchun):
Usage of myapp:
-age int
yosh
-name string
salomlashish uchun ism (default "dunyo")
-verbose
batafsil chiqish rejimi
| Vazifa | Funksiya |
|---|---|
| Satr turidagi flag | flag.String(nom, standart, tavsif) |
| Butun son / mantiqiy flag | flag.Int() / flag.Bool() |
| Flag qiymatini mavjud o'zgaruvchiga bog'lash | flag.StringVar(&o'zgaruvchi, ...) va h.k. |
| Barcha flag'larni o'qish | flag.Parse() (albatta boshqa flag'lardan keyin, ulardan foydalanishdan oldin chaqiriladi) |
| Flag bo'lmagan qolgan argumentlar | flag.Args() |
[!NOTE] Agar CLI dasturingiz murakkabroq bo'lsa (masalan,
git commit,git pushkabi ichki "buyruqlar" — subcommand'lar kerak bo'lsa), standartflagpaketi buni to'g'ridan-to'g'ri qo'llab-quvvatlamaydi. Bunday hollarda ko'pincha jamiyat kutubxonalari (masalan,cobra) ishlatiladi — lekin ular ham ko'p hollarda ichida aynan shuflagpaketiga tayanadi.