flag.Parse în Go

Citește opțiunile din linia de comandă (os.Args) și completează variabilele definite cu flag.String, flag.Int etc.

Sintaxă
func Parse()

Ce face flag.Parse

Pachetul flag are doi pași: întâi definești opțiunile (flag.String, flag.Int, flag.Bool…), apoi apelezi flag.Parse(), care citește os.Args[1:] și pune valorile în variabile. Înainte de Parse, variabilele au doar valorile implicite.

Formate acceptate: -port=9000, -port 9000, --port=9000 (una sau două cratime). Opțiunile booleene se scriu simplu (-v) sau cu valoare (-v=false), dar nu -v false. Citirea se oprește la primul argument care nu e opțiune sau la --; restul ajunge în flag.Args().

La o opțiune necunoscută sau o valoare greșită, Parse afișează eroarea și ajutorul, apoi oprește programul cu codul 2. La -h sau -help, afișează ajutorul și iese cu codul 0.

Ce returnează

Nimic.

Exemple

Exemplul 1: Opțiuni pentru un server

Exemplul nu primește argumente reale, așa că le scriem în os.Args; în practică ai rula ./server -port=9000 -mod productie.

package main

import (
    "flag"
    "fmt"
    "os"
)

func main() {
    os.Args = []string{"server", "-port=9000", "-mod", "productie", "-v"}

    port := flag.Int("port", 8080, "portul pe care ascultă serverul")
    mod := flag.String("mod", "dezvoltare", "modul de rulare")
    detaliat := flag.Bool("v", false, "afișează detalii")
    fmt.Println("înainte de Parse:", *port, *mod, *detaliat)

    flag.Parse()
    fmt.Println("după Parse:      ", *port, *mod, *detaliat)
}

Rezultat

înainte de Parse: 8080 dezvoltare false
după Parse:       9000 productie true

Exemplul 2: Valorile implicite

Fără opțiuni în linia de comandă rămân valorile implicite.

package main

import (
    "flag"
    "fmt"
)

func main() {
    port := flag.Int("port", 8080, "portul")
    mod := flag.String("mod", "dezvoltare", "modul de rulare")
    flag.Parse()
    fmt.Printf("port=%d mod=%s\n", *port, *mod)
}

Rezultat

port=8080 mod=dezvoltare

Exemplul 3: Opțiune necunoscută

package main

import (
    "flag"
    "fmt"
)

func main() {
    port := flag.Int("port", 8080, "portul pe care ascultă serverul")
    flag.Parse()
    fmt.Println("port:", *port)
}

Rezultat în terminal

$ ./server -prot=9000
flag provided but not defined: -prot
Usage of ./server:
  -port int
    	portul pe care ascultă serverul (default 8080)
$ echo $?
2

Greșeli frecvente

  • Citești valorile înainte de flag.Parse(). Primești doar valorile implicite.
  • Scrii opțiunile după argumentele obișnuite: ./program fisier.txt -v. Parse se oprește la fisier.txt, iar -v ajunge în flag.Args().
  • Apelezi flag.Parse() în init() sau în pachete-bibliotecă. Fă-o o singură dată, în main, după ce toate opțiunile au fost definite.

Comenzi înrudite

  • flag.String: Definește o opțiune text (-nume=valoare) și returnează un pointer la valoarea ei.
  • flag.Int: Definește o opțiune număr întreg (-n=10) și returnează un pointer la valoarea ei.
  • flag.Bool: Definește o opțiune da/nu: simpla prezență (-v) o face true.
  • flag.Args: Returnează argumentele obișnuite rămase după opțiuni: toate (Args), unul anume (Arg) sau câte sunt (NArg).
  • flag.Usage: Variabila care ține funcția de afișare a ajutorului; o înlocuiești ca să-ți scrii propriul mesaj de utilizare.
  • flag.NewFlagSet: Creează un set separat de opțiuni, util pentru subcomenzi (git commit, git push) și pentru teste.