flag.NewFlagSet în Go

Creează un set separat de opțiuni, util pentru subcomenzi (git commit, git push) și pentru teste.

Sintaxă
func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet

Ce face flag.NewFlagSet

Funcțiile flag.String, flag.Parse etc. lucrează pe setul global flag.CommandLine. flag.NewFlagSet creează un set independent, cu propriile opțiuni și metode identice: fs.String, fs.Int, fs.Parse(argumente), fs.Args(), fs.PrintDefaults().

errorHandling decide ce se întâmplă la o eroare: flag.ContinueOnError (returnează eroarea din Parse), flag.ExitOnError (oprește programul cu codul 2) sau flag.PanicOnError. Cu ContinueOnError, pentru -h primești eroarea flag.ErrHelp.

Folosirea tipică: subcomenzi. Citești os.Args[1] (de exemplu adauga sau lista), alegi setul de opțiuni al subcomenzii și apelezi Parse(os.Args[2:]).

Parametri

Parametru Descriere
name Numele setului, afișat în mesajele de eroare și ajutor.
errorHandling flag.ContinueOnError, flag.ExitOnError sau flag.PanicOnError.

Ce returnează

Un *flag.FlagSet nou.

Exemple

Exemplul 1: Subcomenzi

package main

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

func main() {
    os.Args = []string{"sarcini", "adauga", "-prioritate=2", "Cumpără pâine"}

    adauga := flag.NewFlagSet("adauga", flag.ExitOnError)
    prioritate := adauga.Int("prioritate", 1, "prioritatea sarcinii")

    lista := flag.NewFlagSet("lista", flag.ExitOnError)
    toate := lista.Bool("toate", false, "include sarcinile terminate")

    if len(os.Args) < 2 {
        fmt.Println("utilizare: sarcini <adauga|lista> [opțiuni]")
        return
    }
    switch os.Args[1] {
    case "adauga":
        adauga.Parse(os.Args[2:])
        fmt.Printf("adaug %q cu prioritatea %d\n", adauga.Arg(0), *prioritate)
    case "lista":
        lista.Parse(os.Args[2:])
        fmt.Println("listez sarcinile, toate:", *toate)
    default:
        fmt.Println("subcomandă necunoscută:", os.Args[1])
    }
}

Rezultat

adaug "Cumpără pâine" cu prioritatea 2

Exemplul 2: Erori tratate în program

package main

import (
    "errors"
    "flag"
    "fmt"
    "io"
)

func main() {
    for _, argumente := range [][]string{{"-n=5"}, {"-x"}, {"-h"}} {
        fs := flag.NewFlagSet("test", flag.ContinueOnError)
        fs.SetOutput(io.Discard) // nu afișăm ajutorul automat
        n := fs.Int("n", 1, "număr")
        err := fs.Parse(argumente)
        switch {
        case errors.Is(err, flag.ErrHelp):
            fmt.Println(argumente, "-> s-a cerut ajutorul")
        case err != nil:
            fmt.Println(argumente, "-> eroare:", err)
        default:
            fmt.Println(argumente, "-> n =", *n)
        }
    }
}

Rezultat

[-n=5] -> n = 5
[-x] -> eroare: flag provided but not defined: -x
[-h] -> s-a cerut ajutorul

Greșeli frecvente

  • Dai lui fs.Parse tot os.Args. Primul element este numele programului, iar parsarea se oprește imediat; dă os.Args[2:] (după subcomandă).
  • Folosești flag.ExitOnError în teste. Testul se oprește; folosește ContinueOnError.

Comenzi înrudite

  • flag.Parse: Citește opțiunile din linia de comandă (os.Args) și completează variabilele definite cu flag.String, flag.Int etc.
  • 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.PrintDefaults: Afișează lista tuturor opțiunilor definite, cu tipul, descrierea și valoarea implicită.