Описание пакета flag языка программирования Go

Пакет flag реализует разбор флагов командной строки.

Использование

Определите флаги с помощью flag.String, Bool, Int и т. д.

Это объявляет целочисленный флаг -n, хранящийся в указателе nFlag, с типом *int:

import «flag»
var nFlag = flag.Int("n", 1234, "сообщение справки для флага n")

При желании можно привязать флаг к переменной с помощью функций Var().

var flagvar int
func init() {
    flag.IntVar(&flagvar, "flagname", 1234, "сообщение справки для flagname")
}

Или можно создать пользовательские флаги, которые удовлетворяют интерфейсу Value (с указателями-приемниками), и связать их с разбором флагов с помощью

flag.Var(&flagVal, "name", "сообщение справки для flagname")

Для таких флагов значением по умолчанию является просто начальное значение переменной.

После определения всех флагов вызовите

flag.Parse()

чтобы проанализировать командную строку в определенные флаги.

Затем флаги можно использовать напрямую. Если вы используете сами флаги, все они являются указателями; если вы связываете их с переменными, они являются значениями.

fmt.Println(«ip имеет значение », *ip)
fmt.Println(«flagvar имеет значение », flagvar)

После разбора аргументы, следующие за флагами, доступны как срез flag.Args или по отдельности как flag.Arg(i). Аргументы индексируются от 0 до flag.NArg-1.

Синтаксис флагов командной строки ¶

Допускаются следующие формы:

-flag
--flag   // также допускаются двойные тире
-flag=x
-flag x  // только небулевые флаги

Можно использовать один или два тире; они эквивалентны. Последняя форма не допускается для булевых флагов, поскольку значение команды

cmd -x *

где * — подстановочный знак оболочки Unix, изменится, если есть файл с именем 0, false и т. д. Для отключения булевого флага необходимо использовать форму -flag=false.

Разбор флагов прекращается непосредственно перед первым аргументом, не являющимся флагом («-» является аргументом, не являющимся флагом), или после терминатора «–».

  • Целочисленные флаги принимают значения 1234, 0664, 0x1234 и могут быть отрицательными.
  • Булевы флаги могут быть: 1, 0, t, f, T, F, true, false, TRUE, FALSE, True, False

Флаги продолжительности принимают любой ввод, допустимый для time.ParseDuration.

Набор флагов командной строки по умолчанию управляется функциями верхнего уровня. Тип FlagSet позволяет определять независимые наборы флагов, например для реализации подкоманд в интерфейсе командной строки. Методы FlagSet аналогичны функциям верхнего уровня для набора флагов командной строки.

Пример
package main

import (
	"errors"
	"flag"
	"fmt"
	"os"
	"strings"
	"time"
)

// Пример 1: Флаг строки с именем "species" и значением по умолчанию "gopher"
var species = flag.String("species", "gopher", "the species we are studying")

// Пример 2: Два флага (длинный и короткий) с общей переменной
var gopherType string

func init() {
	const (
		defaultGopher = "pocket"
		usage         = "the variety of gopher"
	)
	flag.StringVar(&gopherType, "gopher_type", defaultGopher, usage)
	flag.StringVar(&gopherType, "g", defaultGopher, usage+" (shorthand)")
}

// Пример 3: Пользовательский тип флага - срез интервалов времени
type interval []time.Duration

// String реализует интерфейс flag.Value
func (i *interval) String() string {
	if len(*i) == 0 {
		return ""
	}
	var b strings.Builder
	for idx, d := range *i {
		if idx > 0 {
			b.WriteString(", ")
		}
		b.WriteString(d.String())
	}
	return b.String()
}

// Set реализует интерфейс flag.Value
func (i *interval) Set(value string) error {
	// Разрешаем множественные установки флага для накопления значений
	for _, dt := range strings.Split(value, ",") {
		duration, err := time.ParseDuration(strings.TrimSpace(dt))
		if err != nil {
			return fmt.Errorf("invalid duration %q: %v", dt, err)
		}
		*i = append(*i, duration)
	}
	return nil
}

var intervalFlag interval

func init() {
	flag.Var(&intervalFlag, "deltaT", "comma-separated list of intervals to use between events")
}

func main() {
	// Парсим флаги
	flag.Parse()

	// Выводим значения флагов
	fmt.Println("Species:", *species)
	fmt.Println("Gopher type:", gopherType)
	fmt.Println("Intervals:", intervalFlag.String())

	// Пример использования
	if len(intervalFlag) == 0 {
		fmt.Println("No intervals specified. Use -deltaT flag")
		os.Exit(1)
	}

	// Демонстрация работы с интервалами
	for i, d := range intervalFlag {
		fmt.Printf("Event %d will happen after %v\n", i+1, d)
		time.Sleep(d) // В реальном коде здесь была бы полезная работа
	}
}

Как использовать:

  1. Сборка:
go build -o app
  1. Примеры запуска:
# Простой запуск
./app -species=rabbit -gopher_type=arctic -deltaT=1s,2s,3s

# Использование короткого флага
./app -g=arctic -deltaT=500ms,1s

# Просмотр помощи
./app -help

Переменные

var ErrHelp = errors.New("flag: help requested")

ErrHelp - это ошибка, возвращаемая при вызове флага -help или -h, но такой флаг не определен.

var Usage = func() {
fmt.Fprintf(CommandLine.Output(), "Usage of %s:\n", os.Args[0])
PrintDefaults()
}

Usage печатает сообщение об использовании всех определенных флагов командной строки в выходной файл CommandLine, который по умолчанию является os.Stderr.

Функция вызывается при возникновении ошибки во время разбора флагов.

Функция - это переменная, которая может быть изменена для указания на пользовательскую функцию. По умолчанию она печатает простой заголовок и вызывает PrintDefaults; подробности о формате вывода и о том, как им управлять, см. в документации к PrintDefaults.

Пользовательские функции могут выбрать выход из программы; по умолчанию выход происходит в любом случае, поскольку стратегия обработки ошибок в командной строке установлена на ExitOnError.