67 / 68

flag

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.

example.go
import "flag"

[!NOTE] os.Args (oldingi darsda ko'rgan edik) orqali ham argumentlarni o'qish mumkin, lekin flag ularni avtomatik ravishda kerakli turga (string, int, bool) aylantiradi, standart qiymat beradi va -h/-help orqali avtomatik yordam xabarini ham yaratib beradi.


1. Oddiy flag'larni belgilash

example.go
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:

bash
myapp -name=Ali -age=25 -verbose

Natija:

kod
Salom, Ali
Yosh: 25
Batafsil rejim: true

Agar flag'lar berilmasa, standart qiymatlar ishlatiladi:

bash
myapp

Natija:

kod
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.


2. Mavjud o'zgaruvchiga to'g'ridan-to'g'ri bog'lash: 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:

example.go
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):

kod
Server porti: 8080

3. Flag bo'lmagan qo'shimcha argumentlar: flag.Args()

Agar dasturga flag'lardan tashqari, oddiy qo'shimcha argumentlar ham berilsa (masalan, fayl nomlari), ularni flag.Args() orqali olish mumkin:

example.go
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:

bash
myapp -verbose fayl1.txt fayl2.txt

Natija:

kod
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.


4. Avtomatik yordam xabari

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:

bash
myapp -h

Natija (yuqoridagi 1-misoldagi flag'lar uchun):

kod
Usage of myapp:
  -age int
        yosh
  -name string
        salomlashish uchun ism (default "dunyo")
  -verbose
        batafsil chiqish rejimi

Xulosa: qachon qaysi funksiya kerak?

VazifaFunksiya
Satr turidagi flagflag.String(nom, standart, tavsif)
Butun son / mantiqiy flagflag.Int() / flag.Bool()
Flag qiymatini mavjud o'zgaruvchiga bog'lashflag.StringVar(&o'zgaruvchi, ...) va h.k.
Barcha flag'larni o'qishflag.Parse() (albatta boshqa flag'lardan keyin, ulardan foydalanishdan oldin chaqiriladi)
Flag bo'lmagan qolgan argumentlarflag.Args()

[!NOTE] Agar CLI dasturingiz murakkabroq bo'lsa (masalan, git commit, git push kabi ichki "buyruqlar" — subcommand'lar kerak bo'lsa), standart flag paketi 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 shu flag paketiga tayanadi.