Тип flag.FlagSet
Тип flag.FlagSet представляет собой набор флагов командной строки,
который позволяет создавать изолированные группы флагов.
В отличие от глобального flag.CommandLine, каждый экземпляр
flag.FlagSet управляет собственными флагами независимо.
Это особенно полезно при создании сложных CLI-приложений
с подкомандами или при разработке библиотек,
которые не должны конфликтовать с основными флагами.
Структура flag.FlagSet предоставляет те же методы
для определения флагов, что и пакет flag на верхнем уровне,
такие как String, Int, Bool и другие.
Создание нового FlagSet
Для создания нового набора флагов используется функция
flag.NewFlagSet. Она принимает два параметра:
название набора (обычно это имя команды или подкоманды)
и режим обработки ошибок типа flag.ErrorHandling.
Функция возвращает указатель на новый экземпляр
flag.FlagSet, который можно использовать
для определения и парсинга флагов.
package main
import (
"flag"
"fmt"
)
func main() {
// Create a new FlagSet named "server"
fs := flag.NewFlagSet("server", flag.ExitOnError)
// Define flags within this FlagSet
host := fs.String("host", "localhost", "Server host")
port := fs.Int("port", 8080, "Server port")
// Parse arguments for this FlagSet
args := []string{"-host", "192.168.1.1", "-port", "9090"}
fs.Parse(args)
fmt.Printf("Host: %s, Port: %d\n", *host, *port)
}
Результат выполнения кода:
"Host: 192.168.1.1, Port: 9090"
Определение флагов в FlagSet
Экземпляр flag.FlagSet предоставляет те же методы
для определения флагов, что и глобальный пакет.
Все методы возвращают указатель на значение флага,
который становится доступным после вызова Parse.
В отличие от глобальных флагов, каждый набор
хранит свои флаги изолированно, что позволяет
использовать одинаковые имена флагов в разных контекстах.
package main
import (
"flag"
"fmt"
)
func main() {
// Create two independent FlagSets
fs1 := flag.NewFlagSet("cmd1", flag.ExitOnError)
fs2 := flag.NewFlagSet("cmd2", flag.ExitOnError)
// Define same flag names in different FlagSets
verbose1 := fs1.Bool("verbose", false, "Enable verbose mode")
verbose2 := fs2.Bool("verbose", true, "Enable verbose mode")
// Parse different arguments for each FlagSet
fs1.Parse([]string{"-verbose"})
fs2.Parse([]string{})
fmt.Printf("fs1 verbose: %v, fs2 verbose: %v\n", *verbose1, *verbose2)
}
Результат выполнения кода:
"fs1 verbose: true, fs2 verbose: true"
Парсинг аргументов с FlagSet
Метод Parse экземпляра flag.FlagSet
выполняет разбор переданного среза строк.
В отличие от глобальной функции flag.Parse,
которая работает с os.Args, метод Parse
принимает срез аргументов явно и не затрагивает
глобальное состояние. Это позволяет гибко управлять
разбором аргументов для разных команд или подкоманд
в одном приложении.
package main
import (
"flag"
"fmt"
)
func main() {
fs := flag.NewFlagSet("app", flag.ExitOnError)
name := fs.String("name", "default", "User name")
age := fs.Int("age", 18, "User age")
// Simulate command-line arguments
args := []string{"-name", "John", "-age", "30"}
fs.Parse(args)
fmt.Printf("Name: %s, Age: %d\n", *name, *age)
}
Результат выполнения кода:
"Name: John, Age: 30"
Получение информации о флагах
Экземпляр flag.FlagSet предоставляет методы
NFlag для получения количества установленных флагов,
NArg для получения количества позиционных аргументов,
и Arg для доступа к отдельным позиционным аргументам.
Метод PrintDefaults выводит справку по всем флагам
набора, а Visit и VisitAll позволяют
обойти установленные или все определенные флаги соответственно.
package main
import (
"flag"
"fmt"
)
func main() {
fs := flag.NewFlagSet("example", flag.ExitOnError)
fs.String("config", "config.json", "Path to config file")
fs.Bool("debug", false, "Enable debug mode")
args := []string{"-config", "prod.json", "arg1", "arg2"}
fs.Parse(args)
fmt.Printf("Number of flags set: %d\n", fs.NFlag())
fmt.Printf("Number of args: %d\n", fs.NArg())
if fs.NArg() > 0 {
fmt.Printf("First arg: %s\n", fs.Arg(0))
}
fmt.Println("\nDefaults:")
fs.PrintDefaults()
}
Результат выполнения кода:
"Number of flags set: 1"
"Number of args: 2"
"First arg: arg1"
"Defaults:"
" -config string"
" Path to config file (default \"config.json\")"
" -debug"
" Enable debug mode"
Обработка ошибок в FlagSet
При создании flag.FlagSet можно указать режим
обработки ошибок: flag.ExitOnError завершает
программу при ошибке, flag.PanicOnError вызывает
панику, а flag.ContinueOnError позволяет
обработать ошибку программно. Последний режим особенно
полезен, когда нужно использовать собственный механизм
логирования ошибок или интерактивный ввод.
package main
import (
"flag"
"fmt"
)
func main() {
fs := flag.NewFlagSet("parser", flag.ContinueOnError)
fs.String("name", "default", "User name")
// Invalid argument will not cause exit
args := []string{"-unknown", "value"}
err := fs.Parse(args)
if err != nil {
fmt.Printf("Parse error: %v\n", err)
}
// Even with error, we can continue processing
fmt.Println("Program continues after error")
}
Результат выполнения кода:
"Parse error: flag provided but not defined: -unknown"
"Program continues after error"
Смотрите также
-
функцию
flag.NewFlagSet,
которая создает новый экземпляр FlagSet -
структуру
flag.CommandLine,
которая представляет глобальный набор флагов -
функцию
flag.Parse,
которая парсит глобальный набор флагов -
функцию
flag.VisitAll,
которая обходит все зарегистрированные флаги